A compiler-driven frontend framework built around a blueprint DSL.
TardisJS compiles .tardis files to plain JavaScript modules plus a small runtime (~5KB). It uses Proxy-based reactivity with direct DOM bindings (no virtual DOM reconciliation).
This project is experimental and blueprint-first by design. It is meant for teams who want explicit generated output and a small runtime surface.
npx create-tardis-app my-app
cd my-app
npm install
npm run devOr initialize in an existing directory:
npx tardis init
npx tardis devblueprint Counter {
state {
count: number = 0
}
methods {
increment: () => $update(state.count, state.count + 1)
decrement: () => $update(state.count, state.count - 1)
reset: () => $update(state.count, 0)
}
style(tailwind) {
value: "text-6xl font-bold text-center"
actions: "flex gap-4 justify-center mt-8"
btn: "rounded-lg bg-cyan-400 px-5 py-2 text-black font-medium"
}
ui {
<main>
<p class={"value"}>{state.count}</p>
<div class={"actions"}>
<button class={"btn"} @click={methods.decrement}>-1</button>
<button class={"btn"} @click={methods.increment}>+1</button>
<button class={"btn"} @click={methods.reset}>Reset</button>
</div>
</main>
}
}
- Compiler pipeline —
lex()→parse()→compile()generates imperative JS - ~5KB runtime — small client runtime focused on binding and routing
- Proxy-based reactivity — field-level subscriptions trigger dependent effects
- Direct DOM updates — generated code writes to concrete nodes/attributes
- Blueprint sections — explicit
props/state/computed/methods/events/style/ui/script - File-based routing —
pages/index.tardis→/,pages/[slug].tardis→/:slug - Built-in CLI —
init,dev,build,preview
- React / Vue / Svelte are mature and better choices for many production teams today.
- TardisJS is useful if you want to inspect compile output, keep the runtime surface small, and work in a sectioned DSL.
- Trade-off: smaller ecosystem and fewer integrations compared to established frameworks.
my-app/
pages/
index.tardis # Routes derived from file structure
about.tardis
blog/[id].tardis # Dynamic route: /blog/:id
components/
Button.tardis # Reusable components
public/ # Static assets (copied to dist)
tardis.config.js # Project configuration
package.json
| Command | Description |
|---|---|
tardis init |
Scaffold a project in the current directory |
tardis dev |
Dev server with hot reload |
tardis build |
Production build to dist/ |
tardis preview |
Serve built output on port 4000 |
create-tardis-app <name> |
Create a new project in a subdirectory |
// tardis.config.js
export default {
pages: './pages',
components: './components',
outDir: './dist',
port: 3000,
title: 'my app',
head: [
'<script src="https://cdn.tailwindcss.com"></script>',
],
staticDir: './public',
}blueprint ComponentName {
props { } // Typed component inputs
state { } // Reactive local state (Proxy-based)
computed { } // Derived values from state
methods { } // Event handlers and logic
events { } // Lifecycle: onMount, onDestroy, onUpdate
style(tailwind) { } // Named class tokens
ui { } // HTML-like template with reactive bindings
}
Every section is optional. Pages typically omit props; leaf components may omit state.
| Function | Purpose |
|---|---|
$update(ref, value) |
Update state and trigger bindings |
$toggle(ref) |
Toggle boolean state |
$reset(state, initial) |
Reset state to defaults |
$batch(fn) |
Batch updates into single render cycle |
$navigate(path) |
Client-side navigation |
$params |
Read dynamic route parameters |
$back() / $forward() |
History traversal |
$fetch(url, opts?) |
Network request helper |
$if / $each / $show |
Conditional and list rendering |
$portal(el, target) |
Render into external DOM target |
$(selector) |
jQuery-inspired DOM query |
Syntax highlighting for .tardis files is available in vscode-extension/. Install the .vsix file:
- Open VS Code
- Go to Extensions →
...menu → Install from VSIX - Select
vscode-extension/tardisjs-syntax-0.1.0.vsix
git clone https://github.com/devansharora18/tardisjs.git
cd tardisjs
npm install
npm run build # Build compiler + runtime + CLI
npm test # Run test suite
npm run typecheck # Type checking
npm run dev # Watch mode| Script | Description |
|---|---|
npm run build |
Full build (clean + lib + binaries) |
npm run build:lib |
Compiler and runtime only |
npm run build:bin |
CLI binaries only |
npm run dev |
Rollup watch mode |
npm test |
Vitest single run |
npm run test:watch |
Vitest watch mode |
npm run typecheck |
TypeScript check |
npm run publish:check |
Full quality gate |
Working examples are in examples/:
examples/counter/— Counter with increment, decrement, and resetexamples/todo/— Todo list application
.tardis source
→ lex() Tokenize input
→ parse() Build AST
→ compile() Generate JavaScript
→ TypeScript transpile
→ Runtime import rewriting
→ Browser-ready JS module
The compiler transforms blueprint sections into imperative DOM code that references the $runtime object. State uses JavaScript Proxies for fine-grained reactivity — only bindings that read a changed key are re-evaluated.
In practice:
lex()tokenizes blueprint sections and expressions.parse()builds typed AST nodes (state,methods,events,ui, etc).compile()emits DOM creation code + binding/effect wiring.- Runtime updates are driven by Proxy traps and dependency tracking.
The model keeps runtime logic simple, but shifts more responsibility to compile-time transforms and DSL ergonomics.
- Create a branch scoped to one concern
- Add or update tests next to affected subsystem
- Run
npm run typecheck && npm testbefore review - Provide minimal reproduction for parser/compiler defects
MIT