Glossary
One word per thing
ursprung's ubiquitous language. These terms are used verbatim in issues, commit messages, test names and code, and the words listed as avoid are the ones they replaced. This is a glossary only — no implementation detail and no decisions; those are on the record separately.
Modules and boundaries
- Module
- One file the graph can reach — in the application or in a package it depends on. Almost always a TypeScript source file; a Data module is the exception.avoid: file, unit
- Data module
- A JSON file reached by an import. It is a leaf — it has no specifiers of its own — and it carries no Side, whoever owns it.
- Specifier
- The string a module writes to name another one. It is what an edge in the graph carries, because the two Sides resolve it under different Condition sets and one specifier can legitimately name two files.avoid: import path, module id
- External specifier
- A specifier the build deliberately leaves in its output for the host's own module system to resolve, rather than following it into the graph.avoid: external, builtin
- Side
- Where a module is allowed to run relative to the Server boundary — server, client, or shared. Every first-party module declares its side in its filename; third-party modules have theirs inferred.avoid: environment, target, colour, platform
- Server module
- A module whose filename carries
.server.and which may only ever reach the server output. - Client module
- A module whose filename carries
.client.— it reaches the client output and may also reach the server output, because client modules render during server rendering. - A module whose filename carries
.shared., reaching whichever output reaches it. This is a statement about its Side, not about being emitted once for several entrypoints — that is a Common module, and the two are independent. - Server boundary
- The point where a client module imports from a server module. The bundler replaces the import with an RPC stub rather than including the code.avoid: the network boundary, the RPC boundary
- Stub module
- What a server module is emitted as on the client side of a Server boundary — a whole module carrying the server module's export names bound to RPC calls, not code spliced into the importer. So the importer's own body is identical on both sides, differing only in where its specifiers point.avoid: shim, proxy, stub file
- Callable export
- A server module's export that a client module imports by name across a Server boundary, and which is therefore reachable over RPC by anyone who can open the page. Nothing marks one: being imported is what makes it callable, so the set is a property of the client code rather than of the module that declares it.avoid: RPC function, exposed function, endpoint
- RPC root
- The generated object the RPC endpoint hands to a session, carrying exactly one method per Callable export. Because the RPC library has no allowlist of its own — everything reachable on that object is callable — this object is the perimeter, and there is nothing behind it.avoid: API object, service, router
- First-party module
- A module whose real path carries no
node_modulessegment — the application's own source, including a workspace member. It declares its Side.avoid: local module, app code - Third-party module
- A module reached from inside
node_modules. It declares nothing and has no Side; a side suffix in its filename means nothing.avoid: vendor module, external
Building
- The graph
- The single unified module graph the bundler builds from the config file, from which every output is derived.avoid: dependency tree, module map, bundle graph
- Colouring
- Deriving each node's Reach by traversing the graph from its entrypoints. A node's Side is declared or inferred and is an input to colouring, not its output.avoid: tainting, marking
- Reach
- Which outputs a module's own code ended up in — a set drawn from server and client, derived by colouring. Distinct from Side, which says where a module is allowed to run. A server module reached across a Server boundary is not client-reached: what the client output carries is a Stub module, and none of that module's code is in it.avoid: colour, target, placement
- Client root
- A client module reached directly from a server or shared module. Every one is an independent root of the client output; there is no single client entry per Route.avoid: client entrypoint
- Root entrypoint
- The module Wrangler is configured with, carrying the router. There is exactly one, and it is the only server output not reached by an import.
- Route entrypoint
- The emitted module for one Route on the server, imported lazily by the router once it has matched. It carries the Route's own modules and its full ancestor Layout chain, so one import satisfies a matched request. There is one per Route, and no client counterpart — the client output is rooted at Client roots instead.avoid: route bundle, chunk
- Common module
- An emitted module that more than one entrypoint reaches, so the build emits it once and they share it rather than each carrying a copy.avoid: shared module — that word is taken, and means something unrelated (a Side, not a position in the graph); vendor chunk
- Emitted module
- Any module the build writes out, whatever its role. Filenames are content-hashed; a query string is never used to distinguish two of them, because the host's module registry keys on the resolved specifier and would treat
x.js?v=2as a second instance. The Root entrypoint is the one exception to the hashing, because Wrangler is configured with it by name and the build cannot rewrite the configuration to match. - Emission record
- What the build records about one Emitted module — its filename, its provenance, every specifier it wrote and where that resolved, and its content hash. It is what the post-emission audit reads instead of the graph, so that a wrong traversal cannot satisfy the audit by being wrong consistently, and it is the only thing that maps a flat emitted filename back to the module it came from.avoid: manifest, build metadata
- Condition set
- The export conditions a build claims when resolving, one per Side. It is a set: which condition wins is decided by the order the package author wrote their keys, never by ours.avoid: condition list, condition order, target
- Type stripping
- Removing erasable TypeScript syntax from a module while otherwise preserving its JavaScript source.avoid: transpilation, compilation
- Erasable syntax
- The TypeScript constructs that can be deleted without generating replacement JavaScript. Application code may use no others.
- Virtual filesystem
- The injected interface through which the build reads every file. The build never touches a real filesystem, so it can run inside a Worker.avoid: VFS in prose (fine in code), file adapter
- Build host
- Whatever invokes the build. It evaluates the config file, supplies the virtual filesystem and writes the output; it is not part of the build.avoid: CLI, driver, runner
- Request context
- The per-request object every piece of server code can reach — the request being served, the application's bindings, the matched route's params, and the means to extend the request's lifetime. It is ambient rather than a parameter: there is exactly one per request, and reading it outside a request is an error. An API route's handler receives this same object as its second argument; it is one thing reachable two ways, not two things.avoid: env, locals, request-scoped globals, ambient state
- Route table
- The module the build generates from the evaluated route tree, carrying the route set the router matches against at runtime.avoid: manifest, route map
- Reserved client prefix
- The path inside the client output that every emitted client module is served from, and which an application's own static files may not occupy. It exists so the two kinds of file in one directory cannot collide, and so a cache policy has a stable name to address.avoid: base path, public path, mount point
There is deliberately no collective noun for everything the build emits for one side. Say “the server output” or “the client output” in prose. The words server bundle and route bundle were retired on 2026-08-07: each named a single file, and neither is one any more.
Application surface
- Config file
- The application's single entry point, evaluated by the build host before the build begins, from which everything else is discovered.avoid: manifest, ursprung.json
- Route file
- Where the application's routes are declared, imported by the config file.
- Static directory
- The directory an application names in its config file, whose files are copied into the client output wholesale and as opaque bytes. Naming one is optional. A file is eligible because it is in the directory and for no other reason; nothing there is compiled, hashed, or part of the graph.avoid: public directory; assets directory — that name is Wrangler's, and means the destination
- Program
- The one TypeScript compilation an application carries. It holds every file of both Sides and the host files together, because a Server component imports a Client component and the two cannot sit in separate compilations.avoid: side project, tsconfig
- Base config
- The TypeScript configuration ursprung publishes for an application to extend. There is one, and extending it is an application's whole configuration.avoid: preset, template
- Module reference
- How the route file names a module without importing it, resolved against the file that wrote it. It is never loaded during evaluation.avoid: lazy import, thunk, pointer
- Route
- One addressable node in the application's route tree. Nested beneath a root route.
- Canonical URL
- The single URL a route answers at. It carries no trailing slash, and a request whose path differs from it is redirected rather than matched.avoid: normalised path, pretty URL
- Page route
- A route that renders UI. One route may be a page route and an API route at once.avoid: application route, view
- API route
- A route that declares handlers per HTTP method. A handler returns a response and never enters the Walk. Where the route is not also a page route, a method it does not declare is refused rather than rendered.
- Layout
- The component a route contributes to wrap itself and every route beneath it — as opposed to the component it renders when matched exactly.avoid: shell, wrapper, template, slot
- Server component
- A component defined in a server module. Its code reaches the server output only, so its body never runs in a browser.
- Client component
- A component defined in a client module, so its code reaches both outputs. It renders on the server during server rendering and resumes on the client, and its body runs again in the browser whenever a Region creates a fresh instance of it.
Rendering
- Server rendering
- Executing components on the server to produce HTML, streamed to the browser in order.avoid: SSR in prose (fine in code), prerendering
- Resumption
- The client continuing an application that was rendered on the server, without executing the component tree again.avoid: hydration — which is the thing ursprung deliberately does not do
- Resumability payload
- What the server emits alongside the HTML so that the client can resume.avoid: hydration data, state blob
- Awakening
- Running a Client component's body in the browser to recover what the Resumability payload does not carry — its handlers, its live positions and its reactive graph. It is what Resumption does instead of transmitting a closure, it happens on first need rather than on load, and it drives no Host operation.avoid: hydrating, mounting, waking, rehydration
- Address
- What names one position inside a Client root: the root's index, then one level per Descendable position on the way down, then the position's ordinal. It appears in the served markup on the element or on the Region's Anchor, and it is matched by two walks of the same Description tree — never by comparing a walk against the DOM.avoid: node id, index, path
- Addressable position
- A place an Address can name inside one component instance: an element carrying a handler, an element carrying a live attribute, or a Region. Nothing else is numbered, so an instance with none of them contributes nothing to the payload.
- Descendable position
- A place an Address can descend through: a child Client component instance, or one row of a Keyed list. Both are numbered in one sequence, which is what keeps an Address to a root, some levels, and an ordinal. Every component instance inside a Client root is a child Client instance, whether or not the module it came from exports it — the test is where the instance sits, not what it is.
- Host
- The implementation the renderer talks to in order to produce output — the DOM in the browser, a string on the server, and a native UI layer later. Operations flow one way: a Host is written to and never read from. The ones that mutate output already produced are a separate, client-only half, because only a Sink firing can reach them.avoid: renderer, backend, platform
- Anchor
- A Host node with no output of its own, marking where a Region — or one row of a Keyed list — begins or ends. It is what a Region that currently renders nothing has instead of a node, and the only thing that survives into the served HTML to say where one was.avoid: marker, placeholder, comment node
- Recording Host
- A Host that records the operations it receives instead of producing output. It is an implementation of the Host interface alongside the DOM one and the server-string one, not a mock of one, and it is what makes Resumption assertable: a component that ran would have had to create nodes through it.avoid: mock host, test host, spy
- Intrinsic element
- An element ursprung knows natively, as opposed to a component. Explicitly enumerated rather than open-ended, so an unknown name is an error rather than a passthrough. The enumeration carries what the Hosts need to treat the element correctly — its namespace, whether it is void, whether its children are raw text — and not only what its attributes are named.avoid: host element, tag, primitive
- Description
- What JSX evaluates to — inert data naming an Intrinsic element or a component, which the renderer walks in order to drive the Host. It is transient: nothing retains it, and two of them are never compared, which is what distinguishes it from a virtual DOM node. It carries a brand, so that data which merely has the same shape is not mistaken for one.avoid: element, vnode, virtual DOM node, render tree
- Renderable
- Any value allowed in child position or as a component's return value. Wider than a Description — text, nothing, a list, and a live position are all renderable — which is why the two need separate names: every Description is renderable, and most renderable things are not Descriptions. It is the one type whose members differ by Side: on the server a component may also return a response, which ends the render rather than contributing to it, and in child position it may not.avoid: element, node, child, JSX
- Signal
- The unit of reactive state — either written directly or derived from other Signals. Its value is replaced, never mutated, and two values that compare equal are not a change. It is what makes a position live, and the one thing that crosses the Server boundary by identity rather than by value.avoid: observable, ref, atom, store, reactive variable, state
- Live position
- A place in the output — a child or an attribute — whose value depends on a Signal, so that a change flows to it. A position that reads no Signal is static and stays exactly as it was first rendered.avoid: binding, reactive slot, dynamic expression
- Sink
- A reactive expression wired to one position in the output, so that a change flows to that position instead of through a component running again. The word is deliberately not binding, which in this repo means one of the application's Cloudflare bindings.avoid: binding, subscription, watcher
- Effect
- A reactive expression run for its side effect rather than to produce output — a Sink with no position. Like a Sink it belongs to an Owner, and like one it exists only on the client, because the server renders once and has no change to react to.avoid: watcher, reaction, autorun, subscription
- Keyed list
- The construct that gives the items of a list identity. The renderer never learns what a key is — it destroys and recreates Regions and reorders Host nodes by reference — so identity lives here instead, as one Signal and one Owner per item.avoid: repeater, loop, each, map
- Region
- The span of Host nodes bounded by one Anchor pair. It is the unit of destruction and recreation: nothing smaller is ever replaced, and nothing compares what was there before with what replaces it. Almost every Region is produced by one Sink in child position, and that Sink is what rebuilds it; a <Pending> creates one explicitly instead, with no Sink behind it, so that its content can be replaced when the thing it is waiting for settles.avoid: fragment, slot, block
- Owner
- What a Region's contents belong to, and the unit of disposal — it holds the Sinks, the cleanup callbacks and the nested Owners created beneath it, and disposing it releases all of them. A Region has exactly one, and so does each row of a Keyed list; a component instance registers on the nearest one rather than opening its own, because a component instance is never destroyed on its own and a per-instance Owner is therefore unobservable. An Owner that is reused, as a Region's is on every rebuild, stays where it is; one that is discarded, as a removed row's is, leaves its parent as well. Owners exist only on the client; the server renders once and the request ends, so there is nothing there to dispose.avoid: scope — that word is spent on the parser's absent scope model; root, context, lifetime
- Walk
- The traversal that turns a Description tree into Host operations. It produces no output of its own — a Host is written to as it goes — so its only jobs are ordering and suspending. One Walk serves both sides.avoid: render pass, reconcile, traversal, render tree
- Suspension
- The point at which a Walk stops because an async component has not settled. It is the only thing a Walk waits for. A tree containing none runs to completion in one turn. On the server it is also the only place output can leave the isolate, so it is where a flush, backpressure and the response's commit all happen — none of which is true on the client, where a Suspension only ever occurs inside a
<Pending>'s own Driver.avoid: suspense — folklore for semantics ursprung does not have; pause, block, await point - Driver
- What pumps a Walk: it resumes the Walk, awaits each Suspension and calls flush. Flushing belongs to the Driver and to the render entry that commits, never to the renderer, which is why the renderer names no HTML and no stream.avoid: scheduler — that word is spent on the reactive flush; runner, pump, loop
- Commit
- The moment a response's status line and headers stop being ours — the first Suspension, because that is when the body must be handed back for anything to be sent at all. Everything a route wants to say about its response, it says before this; a document that never suspends never commits until it is finished. It is also the earliest moment anything can be sent, since the body stream does not exist before it, so whoever commits flushes there as well.avoid: flush — that is a Host's and happens repeatedly; a Commit is the response's and happens once; send, start, headers sent
- Flush
- The Host operation that hands over everything written to it since the last one. What it decides differs by Host: on the DOM nothing accumulates, so it is a no-op; on the server it moves bytes that were already fixed when they were written. Every task that produced Host operations owes one.avoid: commit — that names the response's, which happens once and is not a Host's; the reactive flush, which is a pass over dirty Sinks and is always qualified; paint, apply, present
Testing
- Fixture application
- A small application built by the test suite to exercise one behaviour. A valid one is a real directory read into a virtual filesystem snapshot; one whose point is a diagnostic is an inline source literal in the test that asserts it, so deliberately broken code never reaches the repo's typechecker or linter.avoid: test app, sample app, example
- Smuggling corpus
- The set of Fixture applications that each attempt one route by which server code could reach the client output. Every case asserts a specific diagnostic or emission shape, and asserts first that the boundary it attacks was actually in the graph — otherwise a fixture that quietly stops resolving turns the whole corpus green.avoid: leak tests, security fixtures, adversarial suite
Where the terms come from
This page mirrors CONTEXT.md in the repository, which is the source of truth. The decisions these terms are used to argue live in the decision records, and the readable version of how they were reached is the blog.