Skip to content

lukeed/comptime

Repository files navigation

comptime

A Zig-inspired build-time evaluation primitive, exposed as Vite and Rolldown plugins.

import { comptime } from "comptime";
import { fibonacci } from "./math";

export const value = comptime(() => fibonacci(10));

With the plugin enabled, the call is evaluated during the build and replaced with a serialized expression:

export const value = 55;

If the plugin is not enabled, the runtime helper throws so missed transforms fail loudly.

View more complex examples

Install

# via rolldown
bun add --dev comptime rolldown

# via vite
bun add --dev comptime vite

Vite

import { defineConfig } from "vite";
import { comptime } from "comptime/vite";

export default defineConfig({
  plugins: [comptime()],
});

Rolldown

import { defineConfig } from "rolldown";
import { comptime } from "comptime/rolldown";

export default defineConfig({
  input: "src/app.ts",
  plugins: [comptime()],
});

API

import { comptime } from "comptime";

let value = comptime(() => expensivePureWork());

comptime<T>(fn: () => T | Promise<T>): T is typed as an identity helper. The plugin requires a single zero-argument arrow function or function expression.

Supported behavior:

  • Imported comptime bindings from "comptime", including aliases.
  • Shadowed local bindings are ignored.
  • Referenced value imports are captured into virtual modules with absolute import paths.
  • Referenced top-level declarations from the origin module are copied into the virtual module.
  • Promise-returning bodies are awaited.
  • Values are serialized with devalue.
  • Build errors include the original call-site location.
  • Vite dev uses server.ssrLoadModule; Vite build and Rolldown build use an internal Rolldown evaluator.

Options

type ComptimeOptions = {
  include?: string | string[];
  exclude?: string | string[];
  timeout?: number;
  env?: string[] | "all" | "declared";
  serializers?: Array<{
    test: (value: unknown) => boolean;
    serialize: (value: unknown) => string;
  }>;
};

Defaults:

  • timeout: 10_000
  • env: "all"

When env is a string list, static process.env.KEY reads must be listed. Dynamic env reads are rejected unless env is "all".

Common Errors

These fail during transform:

comptime(1);
// comptime() requires a single arrow function with no parameters
comptime((value) => value);
// comptime() requires a single arrow function with no parameters
comptime(() => () => 1);
// comptime returned a value that cannot be serialized
comptime(() => {
  throw new Error("something happened");
});
// build fails

Limits

This package does not add browser-side evaluation, disk caching, Webpack support, or esbuild standalone support.

License

MIT © Luke Edwards

About

A Zig-inspired build-time evaluation primitive, exposed as Vite and Rolldown plugins

Resources

License

Stars

Watchers

Forks

Contributors