phunkie/phunkiec

Phunkie preprocessor CLI: compiles .phunkie files into standard PHP

Maintainers

Package info

github.com/phunkie/phunkiec

Type:project

pkg:composer/phunkie/phunkiec

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.1 2026-08-02 21:34 UTC

This package is not auto-updated.

Last update: 2026-08-18 10:32:57 UTC


README

The Phunkie preprocessor. It compiles .phunkie files into standard PHP: for comprehensions and pattern matching are desugared at compile time, so there is no runtime cost.

Usage

phunkiec <input> --out <path> [--watch] [--macro-dir <dir>]... [--macro-file <file>]...
  • <input> — a .phunkie file or a directory of them.
  • --out / -o — output file or directory (required).
  • --watch / -w — keep running, recompiling a source as it is saved.
  • --macro-dir / -m — an extra directory of .syn macros (repeatable).
  • --macro-file / -f — an extra .syn macro file (repeatable).

A short option takes its value either way round, -o build or -o=build.

A .phunkie file is only ever PHP, so it need not say <?php. The compiler opens the file for you, on its own first line. A source that opens its own tag is left exactly as written, so nothing already written has to change.

phunkiec src --out build

Watching

phunkiec --watch -o=build src

Everything under src is compiled once, and then the directory is watched. Saving a source recompiles that source alone, into the same place under build that it holds under src, and reports it:

Compiled 3 file(s) successfully.
Watching src. Press Ctrl+C to stop.
OK src/App/Todo.phunkie (54 lines) → build/App/Todo.php

A new source is picked up without restarting. A source that fails to compile is reported and the watch carries on, so a half-written save costs nothing but the next save.

Changes are noticed by polling four times a second, comparing the contents of each source rather than its timestamp: filemtime has one-second resolution, so two saves inside the same second are indistinguishable by time and the second would be missed.

Removing a source leaves the PHP it produced behind. Deleting generated files on the strength of a poll is a worse failure than leaving one to be cleaned up.

Macros

phunkiec loads macros from three places, highest precedence first (the first matching rule wins):

  1. Explicit — anything passed with --macro-file / --macro-dir.
  2. Discovered — macros shipped by installed composer packages (see below).
  3. Bundled — the rules that ship with phunkiec, in its own macros/.

So a package's rule overrides a bundled one for the same surface syntax, and an explicitly supplied macro overrides everything.

Shipping macros from a package

A library can ship .syn macros for its own types and have phunkiec discover them automatically. Declare a macros directory in the package's composer.json:

{
    "extra": {
        "phunkiec": {
            "macros": "macros/"
        }
    }
}

Every .syn file in that directory is loaded whenever phunkiec compiles a project that has the package installed. This is how phunkie/effect ships the pattern for its own IO — matching an effect IO needs a rule pointing at effect's Referenced\IO, which phunkiec itself does not know about.

Discovery uses composer's runtime metadata (Composer\InstalledVersions), so it sees exactly the packages installed alongside the project being compiled.