niscTypeScript · Apache-2.0DocsGitHub →
Nisc

The AI-native app framework.

The whole application is data, so an AI can read all of it and write any of it, safely, while it runs.

Your whole app is data an AI can read and write, safely, while it runs.

Ask for a screen:

What the model writes

Your app, while it writes

A recorded run, replayed in your browser. The screen is drawn from the JSON as it arrives, and it works when the last line lands.

Get it on GitHub →
What Nisc is

Full-stack, and built for AI at every layer.

Most frameworks were designed for people to write code in, and AI was added later. Nisc was designed the other way round: screens, server, data, permissions and automations are all checked JSON, so a model can write any of them. It runs on Node and Postgres, with your React or Vue components, or with none.

Stop writing components per featureA screen is a layout over the components you already have. React is optional.
Stop writing SQLSay what you want and what shape. The query is stored and called by name.
Stop writing endpoints for your own dataScreens call stored queries directly. You write endpoints only for the outside world.
Stop writing permission checksOne file says who gets what. The server and the database both enforce it.
Stop writing cron jobsAn automation is a row in a table. A plain scheduler runs it.
Stop writing upgrade scriptsA new version of Nisc ships with a migration for what you already wrote.
Your turn

Now make it do something stupid.

An agent can only write what the vocabulary has words for. Here are three things it has no word for. Hand them to the checker.

Read the salaries table

{
  from: ['salaries'],
  fields: ['salaries.amount'],
}

Invent a component

{
  component: 'FluxCapacitor',
  props: { gigawatts: 1.21 },
}

Slip in some code

{
  component: 'Button',
  props: { label: 'Launch' },
  onClick: "fetch('skynet.example')",
}

A program catches these before the app runs, on every change. With generated code, you are the one who has to.

No deploy

Shipping it is ticking a box.

It is launch day. Margaret is the flight director and Wesley is the intern. Each has their own running app. A screen is data, and so is who gets it. One box each.

Margaret’s appflight director
Wesley’s appintern
Deploys: 0

Nobody rebuilt anything. The server keeps one running app per person and sends each of them what they have.

Who writes what

Three models work on a Nisc app. None of them runs it.

Your coding agentClaude Code, Codex, whatever you use. It builds the app before you ship. You saw it at the top.
Nisc agentsSmall models inside the running app. Each writes one kind of document: a query, a screen, an automation. Never code.
The assistantOne per user. It can read and prepare anything that user can. It cannot press a button for them.

The rule is the same for all three. The model writes a document, a program checks it, and what runs afterwards is ordinary software.

Nisc agents

Then your users start asking for features.

A Nisc agent can write almost anything the app is made of, and it cannot write code. So it is safe to let one work while the app is running, for one person, with that person's rights.

Margaret’s appflight director
Margaret asks for
What the Nisc agents write
—
Developers woken: 0

Each one lands on her phone as a new tile. Open it. It is her screen, built from your components, reading only what she may read, and nobody else has it until somebody ticks a box.

The assistant

It can do what you can do. Except press the button.

It reads what you can read and prepares what you can do, then shows it to you. Ask it to prepare the launch, as Margaret and then as Wesley.

Margaret’s appflight director
Margaret’s assistant
What the assistant writes
—
Nothing to jailbreakWesley's assistant was never told a Launch screen exists. No wording of the request can reach it.
A person pressesThe assistant never executes anything. It fills in the screen and shows it. Margaret launches.
No prompt holds this upWhat the assistant can see is built by the server from the permissions file. The model cannot add to it.
Vex, the data layer

Say what you want. Say what shape.

Nobody writes SQL here, and nobody talks to a model. Your code, your coding agent or the assistant sends Vex a sentence and an example of the result. Vex answers in exactly that shape.

This is the whole request

intent:
shape:
Vex has a model write the query, once

What comes back

Same sentence, different shape, different query. The query is compiled under the permissions of whoever asked, which the model never sees.

After that

Then it never asks a model again.

The query you just made has a name now. Your app keeps the name and sends that, plus any values that change. Postgres answers. No model is involved.

1model calls: one for each query you made above
0requests answered since
Everything your app sends now
{
  fingerprint: 'fp_9c1e04',
  context: {},
}

Postgres answers

Nothing sent yet.
A name and valuesThe request cannot change the query. It can only fill in the blanks.
Locked in productionA name nobody stored is an error. The app never falls back to asking a model.
No AI, no modelYour coding agent can write these by hand. Most apps ship with every query stored and call no model at all.
Automations

Written once. Run by a clock.

Somebody says what they want automated. An agent writes it down as a small document and a plain scheduler runs it, reading through a stored query with the permissions of whoever saved it.

Margaret says
What the agent writes, once
Your design system

It looks like your product. Not like ours.

You write the components once. The agent arranges them and cannot invent, restyle or import one. Here is Telemetry, drawn by three sets of components.

Telemetry

0 mAltitude
0Pings
Tank A87 %
Tank B42 %
LOX64 %

What draws the components is an adapter. Nisc ships adapters for React, Vue, plain DOM and two kinds of terminal. Anything else is one more adapter, and the contract is a document your coding agent can read.

Strata and Prism

Nisc will change. What you stored still works.

Prism is the mapping layer under all of Nisc: data in, data out, written as JSON. Strata puts versions on top of it. Every change to a format ships with a Prism mapping from the old shape to the new, and an old document is run through those mappings whenever it is read.

The change

Stored, written at v1

{
  component: 'Button',
  props: {
    colour: 'red',
    label: 'Launch',
  },
}
The Prism mapping that shipped with the change
{
  description: "Button: 'colour' is now 'ink'",
  steps: [{
    kind: 'document',
    at: 'nisc.nova/layout',
    transform: { $update: {
      from: { $ref: '$.document' },
      path: ['props'],
      value: { $renameKeys: {
        from: { $var: 'current' },
        map: { colour: 'ink' },
      } },
    } },
  }],
}

Handed to your app, v2

{
  component: 'Button',
  props: {
    ink: 'red',
    label: 'Launch',
  },
}
Always current when readYour app never handles an old format. The mappings run first, in order, however far behind a document is.
Saved at the newestOnce a document is saved again, it is stored in the current format and no mapping runs for it.
Never guessedA document from a newer version than the reader is refused. The reader upgrades first.
What it adds up to

AI in every part of the app. Trusted in none of them.

Every demo above is one idea used again. Whatever a model produces is a document. A program checks it against one permissions file. Software runs it. That is why the parts fit: the assistant can open a screen an agent wrote a minute ago, an automation reads through a query a user asked for, and a new feature ships when somebody ticks a box.

So you can stop
Stop reviewing AI's pull requestsA program reads every document a model writes, on every change. You read one file.
Stop hoping the prompt holdsWhat AI may see and do is decided in the server. No wording gets around it.
Stop paying a model per requestA model is paid once, when something is written. After that it is software.
Stop deploying to shipA new screen reaches a team when somebody grants it. Nothing is rebuilt.
Stop fearing the agent with the keysAI prepares. A person presses the button, every time.
Stop buying the biggest modelEach job is one narrow kind of document. Small open models do it.
And start
Start merging on a green checkA coding agent builds the feature. It ships when the checker says it is sound.
Start taking feature requests at runtimeA user asks for a screen, and an agent writes it for them alone, in the running app.
Start giving every user an assistantIt reads and prepares as that person, and can never do more than they can.
Start asking your data in sentencesFrom code, from an agent or from the assistant. The answer comes in the shape you asked for.
Start automating in sentencesSomebody says it once. A clock runs it from then on.
Start letting other people build on youA partner ships screens into your app as JSON. None of their code runs in it.
In your stack

It fits into what you already run.

Node and PostgresA set of TypeScript packages. Nothing exotic underneath.
Your components, or noneReact, Vue, plain DOM or a terminal. Bring your design system, or skip the framework.
Your systemsAn endpoint is a function you write. It can call any API, any database, any library.
One package or all of themEach part works on its own. Take the screens without the server, or the data layer without either.
Apache-2.0Fork it and change it. Then it is yours.
On npmpnpm add @niscorp/nisc zod
github.com/moccadroid/niscorp →

No rockets were launched in the making of this page. One was prepared.