CLI and configuration
Initialize, inspect, generate and clean an AOT project.
pnpm jit init
pnpm jit doctor
pnpm jit list
pnpm jit explain
pnpm jit inspect User --stage source
pnpm jit generate
pnpm jit cleaninit writes a typed jit.config.ts in the project root and a starter
*.jit.ts declaration. Review those two files, export only the compiled
operations the application uses, then run generate.
Complete local setup
import { AOT } from "@jit-compiler/jit";
export default AOT.defineConfig({
entries: ["src/aot/**/*.jit.ts"],
patterns: ["**/*.jit.ts"],
output: {
directory: "src/generated/jit",
clean: true,
},
emit: {
subpathModules: true,
manifest: true,
plans: true,
},
types: {
package: "@jit-compiler/jit",
},
});import { JIT } from "@jit-compiler/jit/define";
const UserSchema = JIT.object({
id: JIT.number().int32(),
name: JIT.string().min(2),
role: JIT.union(JIT.literal("admin"), JIT.literal("member")),
});
const UsersSchema = JIT.array(UserSchema);
const selected = JIT.validator(UserSchema).get("is", "parse");
// Grouped import: User.is(), User.parse().
export const User = JIT.compile(UserSchema, {
is: selected.is,
parse: selected.parse,
});
// Standalone exports keep these declaration names exactly.
export const findAdmins = JIT.query(UsersSchema)
.filter((q) => q.eq("role", "admin"))
.compile();
export const watchUsers = JIT.watch(UsersSchema, { key: "id" });pnpm jit doctor
pnpm jit explain
pnpm jit generateimport {
User,
findAdmins,
watchUsers,
} from "./generated/jit/index.js";
if (User.is(input)) {
const admins = findAdmins(users);
const changes = watchUsers(previousUsers, users);
}The generated JavaScript contains the specialized loops and checks but no schema builders or runtime compiler import. Matching declarations preserve the schema-derived types at the import site.
Output layout is automatic. A project-local directory emits index.js and
index.d.ts for normal relative imports. A directory below node_modules
emits a namespaced dual ESM/CommonJS package and exports map.
If no explicit compiled exports are found, generation prints a diagnostic and writes nothing. There is no raw-schema fallback.
Configuration reference
| Option | Default | Purpose |
|---|---|---|
entries | project-root scan | declaration files, directories or globs to load |
patterns | ['**/*.jit.ts'] | patterns applied while scanning a directory |
output.directory | generated/jit | local directory or generated package location |
output.packageName | inferred | namespace override for output below node_modules |
output.clean | true | remove known artifacts from the previous generation |
emit.subpathModules | false | emit one import entry per declaration file |
emit.manifest | false | record modules, imports, exports and generated files |
emit.plans | false | write deterministic plans for review and CI |
types.package | @jit-compiler/jit | source of JIT.Typeof/strict helpers in declarations |
Discovery
entries accepts files, directories and globs. Directory scans use patterns
(default **/*.jit.ts) and skip node_modules, dot directories and generated
output. Omit entries to scan from the project root.
import { AOT } from "@jit-compiler/jit";
export default AOT.defineConfig({
entries: ["src/schemas/**/*.ts", "jit"],
patterns: ["**/*.jit.ts", "**/*.schema.ts"],
});Output modes
Generate into node_modules/@jit/generated when consumers should import
@jit/generated. Generate into src/generated/jit for
./generated/jit/index.js. No # import alias or nested-package toggle is
required.
export default AOT.defineConfig({
entries: ["src/**/*.jit.ts"],
output: { directory: "src/generated/jit", clean: true },
emit: { subpathModules: true, manifest: true, plans: true },
types: { package: "@jit-compiler/jit" },
});clean: true removes only known generated files before a new generation. It
does not recursively delete arbitrary user files.
Generated package output
For package-style imports, place output below node_modules:
import { AOT } from "@jit-compiler/jit";
export default AOT.defineConfig({
entries: ["src/aot/**/*.jit.ts"],
output: {
directory: "node_modules/@jit/generated",
packageName: "@jit/generated",
clean: true,
},
emit: { subpathModules: true, manifest: true },
});import { User } from "@jit/generated";
import { watchUsers } from "@jit/generated/users";This layout writes index.mjs, index.cjs, matching declarations and a
generated package.json exports map. Run generation after dependency installs,
because package managers own and may replace node_modules.
Diagnostics workflow
doctor: resolved config, patterns, output and discovered files.list: buildable grouped and standalone exports.explain: why each declaration can/cannot build.inspect --stage plan: normalized operation descriptor.inspect --stage source: exact generated JS.inspect --stage declaration: public generated types.
Use this sequence in CI before generation when config drift should fail early.
explain and inspect are especially useful for callback-bound operations.
The CLI reports a serialization boundary instead of silently embedding an
arbitrary runtime closure into generated code.
CI
Run generate in a clean checkout and fail when generated files differ. This proves declarations are current and prevents local stale artifacts from hiding missing exports.
pnpm jit doctor
pnpm jit generate
git diff --exit-code -- src/generated/jitWhen generated files are intentionally excluded from source control, run
pnpm jit generate before the application build and cache the output directory
as a build artifact instead.