Applied Laziness: The "Zero-Infrastructure" Stack

Stop building pipelines. Start shipping logic.


The Problem

You wanted to build a feature. Instead you're debugging webpack configs, waiting for Docker builds, and wondering why your TypeScript types don't match reality.

The modern stack has become a tax on productivity. Every "improvement" adds another layer of indirection, another config file, another thing that can break.


The TJS Win

"I write the type as an example, and I get validation, documentation, and autocomplete for free."

TJS flips the script on types. Instead of describing what a value could be, you show what it looks like:

// TypeScript: describe the abstract shape
function greet(name: string): string

// TJS: show a concrete example
function greet(name: 'World'): '' {
  return `Hello, ${name}!`
}

The type is the example. The example is the documentation. One thing, not three.

What You Stop Doing

What You Start Doing

That's it. No build server. No bundler. No transpilation step. The loop is: write → run.

The "Oops, It's Robust" Moment

Here's the happy accident: you left Safe Mode on.

You didn't write validation logic. You didn't write if (x == null) throw. You just wrote function add(x: 0).

Because you left Safe Mode on, your function now automatically rejects bad inputs with a clean, traceable report:

{
  $error: true,
  message: "Expected 'number', got 'banana'",
  path: "add.input.x"
}

You accidentally built an enterprise-grade API while prototyping.

This is the physics change: In every other language, a type error at runtime is a catastrophe—uncaught exception, stack trace, 500 server error. In TJS Safe Mode, a type error is just data. You trace the error to the source (the caller), not the symptom (the crash).

Mode Behavior The "Oops" Factor
Unsafe (!) "Trust me, bro." Fast, loose. You write tests to catch edge cases.
Safe (?) The Contract. Inputs validated, outputs guaranteed. "I forgot to turn it off, and now my API is bulletproof."

Laziness = Quality. You did less work (no validation code), got a better result (robust contracts).


The AJS Win

"I don't deploy microservices. I save AJS records to Postgres. My 'deployment' takes 10ms."

AJS compiles to JSON. Your agent is a database record:

INSERT INTO agents (name, logic) VALUES (
  'summarize-article',
  '{"$seq": [{"$op": "httpFetch", ...}, {"$op": "llmPredict", ...}]}'
);

Want to update the agent? Update the row. Want to A/B test? Query different rows. Want to audit what changed? git diff the JSON.

What You Stop Doing

What You Start Doing

Your "deployment" is a database write. Your "rollback" is loading the previous row.


The Stack You Delete

Before After
TypeScript TJS
Webpack / Vite / Babel Browser
node_modules (300MB) Import URLs
Source maps Direct execution
Build server Nothing
Microservices One endpoint
Docker / K8s A function call
CI/CD for logic Database write

The Vibe

This isn't about doing less work. It's about doing the right work.

Every hour you spend debugging build tools is an hour you're not shipping features. Every deployment pipeline you maintain is cognitive overhead you carry forever.

TJS and AJS are opinionated about one thing: the fastest path from idea to running code wins.

If your stack disagrees, your stack is wrong.


Who This Is For


For TypeScript Developers Who Don't Care About TJS

You're happy with TypeScript. You don't want a new language. Fine.

You can still use TJS tooling for one thing: inline tests that live with your code.

// mymath.ts - normal TypeScript
function add(a: number, b: number): number {
  return a + b
}

/*test 'adds positive numbers' {
  expect(add(2, 3)).toBe(5)
}*/

/*test 'handles negatives' {
  expect(add(-1, 1)).toBe(0)
}*/

The /*test ... */ comments survive TypeScript compilation. TJS extracts and runs them.

What You Get

How It Works

import { extractTests, testUtils } from 'tjs-lang'

// Read your compiled JS (or TS source)
const source = fs.readFileSync('mymath.js', 'utf-8')

// Extract tests from comments
const { tests, testRunner } = extractTests(source)

// Run them
const result = eval(source + '\n' + testUtils + '\n' + testRunner)
// { passed: 2, failed: 0 }

That's it. You don't adopt TJS. You don't change your types. You just get inline tests for free.

Set safety none and keep living in your world. We're not here to convert you.


Quick Start

npm install tjs-lang
import { tjs, AgentVM } from 'tjs-lang'

// TJS: types as examples, runs in browser
const greet = tjs`
  function greet(name: 'World'): '' {
    return 'Hello, ' + name + '!'
  }
`

// AJS: logic as data, runs in sandbox
const agent = ajs`
  function process({ url }) {
    let data = httpFetch({ url })
    return { fetched: data }
  }
`

const vm = new AgentVM()
const result = await vm.run(agent, { url: 'https://api.example.com' })

That's the whole stack. No config files. No build step. No deployment.


Learn More