Write code that
reads like prose.
10x is a Literate programming language. .md files are programs —
prose is ignored, expressions evaluate inline, compile to ESM, and power
reactive web components.
You write .md files — headings, paragraphs, bullet lists — and embed expressions anywhere. The interpreter ignores prose and evaluates code directly. The compiler emits a clean ESM module. The runtime powers reactive UIs. One source file, three modes.
Numbers, units,
ranges & symbols.
Arithmetic and unit conversion are first-class. Ranges expand lazily. Symbols are lightweight tagged values. Every expression returns a result.
Lambdas, closures,
and pipe composition.
Functions are first-class values. Multi-arg lambdas with
(a b) ->
syntax. Pipe sequences with |>.
Memoization with bang !.
add = (a b) -> a + b. double = n -> n * 2. square = n -> n * n. add(3, 4). double(7). square(7). fib = n -> @if (< n 2) 1, (< n 1) 0 @else fib(n - 1) + fib(n - 2). fib!(12).
The file is
the program.
10x source files are plain Markdown. Headings and paragraphs become documentation. Code expressions evaluate in order. No special fences or delimiters — the language lives alongside the prose.
start prop when provided.count automatically.<h1 class="count">#{count}</h1>.
Reactive state,
automatic re-render.
@signal creates observable state.
@computed derives values.
@render subscribes automatically — no manual updates ever.
count = @signal 0. @render "#app" @shadow @html <div class="sig-root"> <div class="sig-value">#{count}</div> <button id="inc">increment</button> <button id="reset">reset</button> </div>. @on :click "#inc" @shadow count = count + 1. @on :click "#reset" @shadow count = 0.
Shadow DOM,
props & scoped state.
Write a .md file, compile to a
setup(host) function.
Each component instance gets independent signals. Props flow in
via @prop. Styles stay scoped.
count = @signal @prop "start" 0. @render @shadow @html <div class="ctr-root"> <div class="ctr-value">#{count}</div> <button id="dec">−</button> <button id="inc">+</button> <button id="reset">reset</button> </div>. @on :click "#inc" @shadow count = count + 1. @on :click "#dec" @shadow count = count - 1. @on :click "#reset" @shadow count = @prop "start" 0.
Source to portable
ESM in one pass.
The compiler walks the same AST the interpreter uses. Signals, effects, and event handlers become standard JS exports. Output runs in Node, Bun, Deno, and any browser — no runtime overhead.
# signals.md count = @signal 0. double = @computed count * 2. @render "#app" @html <h1 class="count">#{count}</h1>. @on :click "#inc" count = count + 1.
// signals.md → ESM export const count = $.signal(0, "count"); const double = $.computed(() => $.read(count) * 2); $.render("#app", $.html(() => $.h("h1", { class: "count" }, $.read(count)))); $.on("click", "#inc", () => { count.set($.read(count) + 1); });
Import only what you need.
Three packages. Zero coupling. Works in Node, Bun, Deno, and browser.
- signal, effect, read
- computed, batch, untracked
- style
- Pure JS — no DOM dependency
- render, renderShadow
- on, h
- html template tag
- Browser-only reactive layer
- head, tail, map, filter
- take, drop, range
- concat, zip, size
- Works in all JS runtimes
Built to be edited
and extended.
From syntax queries to live reloading — the full language toolchain.
Tree-sitter Grammar
Full concrete syntax tree. Syntax queries, pattern matching, and structural editing.
shippedLanguage Server
Hover docs, diagnostics, completions. Works in any LSP-compatible editor.
shippedZed Extension
Native syntax highlighting in Zed. Powered by the Tree-sitter grammar.
shippedVite Plugin
HMR for .md modules. Import 10x files directly in your Vite project.
CSS & Styles
Raw CSS strings, object styles, and auto-generated atomic utilities.
@style "body { margin: 0; }". @style "h1 { color: #2dd4bf; }". @render "#app" @html <div class="flex p-4 gap-2"> <h1>Hello!</h1> </div>.
VDOM Directives
Native somedom attributes: d:*, s:*, and ref.
open = @signal :on. name = @signal "". el = @signal :nil. @render "#app" @html <input d:model={name} d:show={open} ref={el} />.
Bundler CLI
Bundle local modules and path aliases into a single portable artifact.
10x compile app/main.md --bundle 10x compile app/main.md --bundle \ --alias "@app=./src" bun run app.js node app.js
See it run.
Edit any snippet — results and signals update instantly.
Up and running
in seconds.
Clone, install, and try the REPL — or feed a
.md file
directly to the interpreter. The live demo above runs the same engine in your browser.
# install bun install # interactive REPL bun run repl # run a program node bin/cli examples/fib_memo.md # compile to ESM 10x compile examples/x-counter.md # browser demo make demo