Experiments
streng · dutch, “strict” · rhymes with “length”

All of the corpus.
None of the supply chain.

Streng is a strict, closed-world dialect of TypeScript 7 and the standard library TypeScript never had. The compiler is vendored, the runtime is owned, the registry does not exist. One binary. One Postgres. Every model on earth already writes it fluently — and nothing it writes can import what you didn't ship.

app/*.ts what humans and models write
streng tsgo 7 + engine + stdlib · one binary
./crm your product, one file
postgres:// the only other thing
Premise

The compiler stopped needing the ecosystem it serves

For a decade, “TypeScript without npm” was a contradiction in terms — the compiler itself was a Node program. To typecheck a single file you installed the runtime, the package manager, and the resolution algorithm of the very ecosystem you might have wanted to escape. TypeScript 7 ended that: the compiler is now native Go — ten times faster, and, the part that matters here, embeddable. A library you link, pin, and vendor. The moment the toolchain stopped requiring the ecosystem, keeping the ecosystem became a choice.

And the ecosystem is the worst liability in software. The registry is the most attacked supply chain in the industry, and the newest attack is aimed at machines: models hallucinate plausible package names, attackers register them, and the install succeeds. The frameworks churn on a two-year treadmill. The runtimes are companies — one foundation-run, two venture-funded. And an entire mitigation industry — SBOM scanners, dependency firewalls, lockfile auditors — exists to sell back the safety the architecture gave away.

Meanwhile the language carries the single most valuable asset in the agent era: the largest training corpus of any programming language. Every frontier model writes TypeScript better than it writes anything else. The corpus and the ecosystem were never the same thing. Streng is the split, executed: keep the language every model speaks; delete the world it learned to depend on.

The flip

Sell the absence, not the access

Every TypeScript framework since 2012 has made the same pitch: access — to two million packages, to the component ecosystem, to whatever npm has. Streng inverts the pitch entirely. The product is what cannot happen:

A hallucinated import is a compile error

import resolves against std/ and app/ — or it does not resolve. Slopsquatting, the attack where registrars squat the packages models invent, has no surface: there is no registry to squat. The corpus's most dangerous habit is fail-closed.

The SBOM is one sentence

“This binary, and Postgres.” The dependency audit, the license scan, the transitive CVE triage, the socket-dev subscription — the entire procurement gauntlet collapses, because there is nothing to enumerate.

The churn is deleted

The dialect is frozen, the stdlib versions with the binary, and there is exactly one version of everything. Diamond dependencies are unrepresentable. The two-year framework treadmill isn't survived — it has nowhere to run.

The tooling is inherited anyway

The one thing you'd fear losing — the editor plane — comes free. tsgo's LSP, VS Code, and syntax highlighting in every tool on earth already speak the dialect, because the dialect is TypeScript. No sibling in this family gets its editors on day one. This one does.

The corpus is the one dependency that can't be rugged. Model fluency is irrevocable — no license change, acquisition, or registry policy can claw back what is already trained into every frontier model. Streng treats the corpus as the asset it is, and the ecosystem as the liability it became. That is the whole architecture, stated once.
The stack

Five layers, one binary, one database

Each layer is a small framework kernel with a Dutch name and a familiar ancestor. All of them ship inside the streng binary; streng build links your app, the stdlib, and the engine into one executable.

Streng the dialect
ancestor · typescript 7 A strict subset — subtract, never add. No any, no unchecked casts, no eval, no prototype mutation, no ambient declarations, no imports outside the world. Zero new syntax: the corpus is the spec, and fluency is the moat.
Grond “ground”
ancestor · the stdlib typescript never had HTTP, SQL, crypto (vetted AEAD + KDF, pinned — the one “nothing hand-rolled” exception), time, money, mime, csv, test, and the closed ~25-component vocabulary. Complete for the SaaS envelope, versioned with the binary. import only ever names the world.
Erf “inheritance”
ancestor · ash Declarative resources: one declaration derives schema, migrations, history, policy, PII vault routing, forms, and API. TypeScript is the only mainstream language whose type system can type the derivations exactly — template-literal and conditional types are the macro layer, and the compiler is the first verifier.
Scherm “screen”
ancestor · liveview Server-diffed typed components from the closed vocabulary — static parts sent once, dynamic bindings tracked, byte-sized patches over SSE. Real HTML first paint, no SPA, no hydration, no frontend build pipeline. The renderer ships in the binary.
Taak “task”
ancestor · oban + dbos Durable workflows checkpointed as rows — effect and checkpoint in one transaction, exactly-once by Postgres. Queues, cron, and retries are delayed rows. Enqueue commits with the data that caused it, or not at all.
Kooi “cage”
ancestor · kern's governed evaluation The same interpreter, fuel-metered and capability-scoped, for tenant customizations and agent-written patches. Untrusted code is priced, not trusted — exact step and allocation budgets, capabilities bound in the environment or unnameable.
Go + Postgres substrate
the only dependencies tsgo 7 vendored as a Go library — Apache-licensed, pinned, a file in the repo. An owned pure-Go engine sized to the subset. Go's stdlib for HTTP/TLS/crypto, an owned Postgres wire client over net.Conn. No cgo, no Node, no npm — anywhere in the toolchain.
The subset shrinks the pond. Owning a JavaScript engine is the scary part — but streng doesn't need JavaScript, it needs the subset. No eval, no with, no Proxy, no prototype chains to mutate, no sloppy mode: every construct banned for the corpus's sake also shrinks the engine that must be owned. A smaller language needs a smaller pond — and the two hard parts that remain (Unicode, IEEE 754) are the two Go's stdlib already carries.
The world

A closed world owes you the batteries

In an open ecosystem, a missing battery is an npm install away. In a closed world, a missing battery is a wall. Deleting the registry therefore creates an obligation the registry never had: std/ must cover the entire B2B envelope, or the closed world is a cell instead of an estate. That obligation is the product — “batteries included” is a treadmill claim in an open world; in a closed one it is the definition of usable.

std/identity — in the core, not an add-on

Orgs, users, roles, sessions, and API keys as capability grants. Identity ships in the core because policy, horizons, and audit are structurally built on it — the family rule, held.

std/ui — the component library, two tiers

The closed ~25-primitive vocabulary, plus the derived tier: forms from resources, data tables, boards, dashboards, and the operator plane. Polish overlays derivation — a hand-built component admits into the same slot a derived one filled.

std/taak — the workflow engine

Durable steps, queues, cron, retries, and human-in-the-loop approvals — checkpoints as rows, exactly-once by Postgres. The engine every B2B product builds badly, in the world from day one.

std/erf — the data layer, compliance-grade

Resources, migrations, history, org-scoped policy, and the PII vault with crypto-shred erasure. The parts every from-scratch stack gets last ship with the world, not after it.

std/mail · std/files · std/i18n

Transactional email with templates, CSV import as a dry-run transaction, PDF rendering, locale-aware money and dates, translations as catalog rows. The unglamorous 20 packages every SaaS installs, authored once, audited once.

std/test — because a test dep is still a dep

The runner, fixtures, fakes for every std boundary, and red-path helpers, in the binary. The verification story has no external packages either — the loop stays closed end to end.

How the world grows. New batteries enter by being authored or vendored into std/ — audited once, versioned with the epoch, never resolved from a registry. The bar is the Rule of Three: a battery ships when the third product needs it, and what a product genuinely needs sooner arrives as a framework-authored, capability-gated binding. The world is complete for its envelope, not for every envelope — and the envelope is stated: B2B SaaS.
The dialect

The gate teaches the corpus its manners

A model's first draft arrives with the ecosystem's reflexes — a lodash import, a zod schema, an as any to make the red squiggle stop. The gate answers in milliseconds, with the fix in the error. This conversation is the adoption path, and it converges because the loop is fast:

what the habit writesdeal.ts
import isEqual from "lodash-es";
import { z } from "zod";

const input = z.object({ amount: z.number() })
              .parse(body);

const total = rows.reduce(sum) as any;

// three reflexes from the old world —
// each one learned from the corpus,
// each one a liability here
streng check · 84 ms
what the gate answers3 errors · 0 packages consulted
deal.ts:1"lodash-es" is not in the world.
  std/iter has deepEqual.
  fix: import { deepEqual } from "std/iter"

deal.ts:2 — validators are derived, not imported.
  Deal already knows its shape.
  fix: Deal.parse(body)

deal.ts:7 — `as any` never admits.
  total is Money when rows is Line[].
  fix: annotate rows: Line[]

The canonical artifact is the resource — plain TypeScript, no new syntax, and the type system is strong enough that the derived surface is exactly typed. In TypeScript, types are opinions that erase at runtime. In streng they are laws: every boundary type compiles to a validator, derived from the declaration, never imported from a vendor.

erf · a resource — plain typescript, everything derivescrm/deal.ts
import { resource, states, money, pii, contact, belongsTo, by, orgScoped, role } from "std/erf";

export const Deal = resource("deal", {
  stage:   states("draft", "won", "lost"),  // history: every version
  amount:  money(),
  owner:   pii(contact()),                     // vault-routed · masked by default
  company: belongsTo("company"),
}, {
  horizon: by("assignment"),                  // who syncs / sees this row
  policy:  orgScoped.and(role("sales")),
});

// typeof Deal.Row is exact — the compiler is the first verifier.
// Deal.parse is the derived validator — types don't erase, they enforce.
// schema, migration, history, forms, REST + OpenAPI: derived, catalogued.
taak · a durable workflow — checkpoints are rowscrm/follow-up.ts
export const followUp = workflow(async (wf, dealId: DealId) => {
  await wf.step(sendIntro(dealId));
  await wf.sleep(days(3));                   // a row — survives deploys
  const ok = await wf.receive(Approval);     // waits for a human, or an agent
  if (ok) await wf.step(sendContract(dealId));
});
kooi · tenant & agent code — priced, not trustedhooks.ts
const verdict = await kooi.run(tenantHook, {
  capabilities: ["crm.read"],   // anything else is unnameable in the environment
  fuel: 1_000_000,              // exact step + allocation budget
});
the whole toolchainshell
$ streng check     # tsgo 7, vendored — the full graph, warm, in double-digit ms
$ streng test      # the runner ships in the binary
$ streng build     # ./crm — engine + stdlib + your app, one file
$ ./crm postgres://…   # there is nothing to install, anywhere in this transcript
Restraint

What Streng refuses to have

Every exclusion is load-bearing. Most remove a vendor; the rest remove a way for the corpus's bad habits to become your incident.

package.json
No resolution algorithm, no lockfile, no install step, no registry. The world ships inside the binary, and import either names it or fails.
any · as
The unsound corners are how the corpus lies to itself. A type the gate can't trust is a validator it can't derive — so the gate refuses the lie at admission.
eval · new Function
Code can't manufacture code at runtime. The engine gets smaller, the sandbox gets honest, and the fuel meter can't be escaped by string.
new syntax
Subtract, never add. Fluency is the moat — a construct no model has trained on is a bug in this design, not a feature of it.
node · deno · bun
A runtime with a board of directors is a dependency with a strategy. Streng's engine is owned, pure Go, sized to the subset it must run and nothing more.
semver ranges
One version of everything: the epoch's. Diamond dependencies, peer-dependency hell, and the upgrade matrix are unrepresentable, not solved — moving forward is one atomic step, and it's optional.
The epoch

Frozen between versions. Atomic across them.

Streng is not frozen at TypeScript 7 forever — it is frozen between epochs. When a new TypeScript's idioms have earned their place in the corpus, streng ships a new epoch: dialect, engine, stdlib, component library, workflow engine, and gate, upgraded together, as one artifact. “One version of everything” cuts both ways — nothing drifts between upgrades, and an upgrade is everything at once.

Because there is exactly one version of everything, migration is a property of the gate, not a research project. There is no dependency matrix, no peer solver, no “which combination of package versions works together” — the combination space has two points: the epoch you are on, and the one you are moving to. The gate re-checks the entire application against the new world and reports every incompatibility at once, fix in the error. Hours of listed, mechanical fixes instead of weeks of archaeology.

the whole framework, compliant in one goshell
$ streng migrate 8            # dialect + engine + stdlib + gate move together
checking app/ against epoch 8 … 41 files · 214 ms
12 incompatibilities · every one listed · fixes in the errors

$ streng migrate 8 --commit   # one world, one step — the app and the framework land together
epoch 8 · 0 errors · nothing else in the company noticed

And an epoch is an offer, not an eviction. The old binary is complete and eternal — staying on epoch 7 is a supported posture, not abandonment, because a closed world has no transitive dependency quietly dropping support underneath you. The discipline is Go's compatibility promise applied to an entire framework — and it is precisely the discipline the open ecosystem cannot have, because nobody owns the whole world at once. Streng does. That is the point.

The family shape, again. Kern re-verifies every tenant overlay against every base release; samen gates every merge behind sixteen fail-closed verifiers. The epoch is the same move at framework scale: breakage surfaces at the gate, named and exhaustive, before the upgrade lands — never at runtime, after.
Agent experience

The best agent language was trained, not designed

Taal's premise was that you must invent a language to get a canonical corpus and a fast verifier. TypeScript 7 broke the premise: the largest corpus in existence now has the fastest typechecker ever shipped for it. Streng doesn't build the agent language — it fences the one the agents already have.

The corpus × the checker

Deepest fluency of any language, times a full-graph typecheck in double-digit milliseconds, embedded in the binary. The tightest write-verify loop available in any language, mainstream or invented — and nothing had to be trained.

Grounded by construction

Resources are catalogued in Postgres; the closed world means what isn't in the catalog can't be named, and what isn't in std/ can't be imported. The MCP server ships in the binary: agents query the catalog, not grep.

Diagnostics as API

Every gate error states what's wrong, where, and one concrete fix — machine-stable format, human-legible prose, the std/ replacement named when an import fails. The error channel is the onboarding.

The editor plane is free

tsgo's LSP already speaks the dialect, so VS Code, cursor position, hover types, and rename-across-project work on day one. Streng inherits Microsoft's decade of editor investment without inheriting Microsoft's ecosystem.

The endgame: agents write the language they know best, against a stdlib that is the whole world, gated by a checker that answers in the time a keystroke takes — and the classic failure modes of machine-written code (invented packages, unsound casts, drifting validators) are not reviewed away but unrepresentable.

What we won't pretend

The honest edges

The interpreter is the tax.

An owned pure-Go engine has no JIT; on compute-bound code it will lose to V8 by an order of magnitude. The envelope argument is the defense — the median SaaS is I/O-bound, the heavy lifting lives in SQL, and the reactor stays thin — and the escape is held in reserve: verified hot functions AOT-compiled to Go, taal's lane, opened per-function when production says so. Named, not waved away.

The gate will fight the corpus on day one.

Models write lodash imports and as any by reflex. The bet is that a sub-100ms loop with the fix in the error converges in one or two rounds — the corpus advantage is fluency, not verbatim reuse. That's a measurable claim and a thesis, not a fact; it is the first thing a prototype must measure.

Owning an engine is owning a pond.

The subset shrinks the language but not the numbers, the Unicode, or the async semantics. Conformance is a test262-subset burden carried forever, red-path first. This is kern's pond with a smaller shoreline — smaller is not small.

Epochs answer the drift — and epochs are real work.

Between epochs, the corpus trains on the living language: models will write TypeScript 8 idioms at an epoch-7 gate, and the fix loop absorbs the difference until the next epoch ships. Each epoch is then a whole-world audit — dialect, engine semantics, stdlib, and every derived surface, re-verified in one pass. That converts continuous churn into work priced once per epoch and paid by the framework team, which is the trade chosen — but when a new epoch changes runtime semantics, the owned engine re-digs part of its pond. That's the expensive line item, named.

There is no FFI, and that will cost real adopters.

The only door into the binary is framework-authored, capability-gated bindings — third-party code enters by being vendored and audited into std/, never by an app-level hatch. Stripe's SDK, a PDF library, an ML runtime: each is a deliberate framework decision, not an npm install. A real constraint, chosen on purpose, priced in adoption.

Microsoft still steers the language.

Apache-2.0 fork rights, a pinned vendored compiler, and a frozen subset bound the risk; they don't delete it. What can't be taken back is the corpus — and the corpus, not the trademark, is the dependency streng actually has.

The pitch, in one sentence: your language is the one every model already speaks; your entire dependency graph is one binary and one Postgres you can point at; and nothing in your product can import what you didn't ship.