DEV Community

Yuki Nishikawa
Yuki Nishikawa

Posted on

Web Backend Development Is a Lie: The Lost 15 Years of Betrayal Part Ⅱ Dia.ts: Forging the New Backend Era

⚔️ Part II — Dia.ts: Forging the New Era

"The clock isn't just ticking. It’s almost out of time."

That’s where we left off. And now, we rebuild.


🧱 The Philosophy: Intent Over Endpoints

Every major backend framework gives you options — too many of them.

REST, RPC, GraphQL, decorators, middlewares, services, DAOs...

Dia.ts rejects all of it.

There is only one way to define an API: As an intent.

export const api = defineAPI({
  input: z.object({ name: z.string() }),
  async handler({ input }) {
    return { message: `hello ${input.name}` }
  }
})
Enter fullscreen mode Exit fullscreen mode

Because freedom without structure becomes chaos.

APIs are not CRUD functions. They are contracts that fulfill intent.

✅ Enforced by design:

  • Type-safe contracts from client to server
  • Pure functional middleware with AbortSignal support
  • Zero dynamic routing — everything precompiled

This isn’t “minimalism.”
This is intentional design — APIs as behavioral declarations.


🧠 Query as Intent

What if instead of asking for data, clients could declare what they want to happen?

"I want to mark this task as done."

Not: "Give me todos where done = false"

Dia.ts supports Intent-based APIs — where the handler isn’t just a fetcher, but a fulfillment engine.

// intent: "mark_done"
export const api = defineAPI({
  input: z.object({ id: z.string() }),
  async handler({ input }) {
    return markTodoDone(input.id)
  }
})
Enter fullscreen mode Exit fullscreen mode

This structure:

  • 🌟 Aligns better with product UX
  • 📚 Logs like event history
  • 🛡 Centralizes auth & validation
  • 🧠 Enables future AI/LLM integrations

APIs stop being endpoints. They become declarative interfaces for action.


⚙️ The Architecture: Composable, Cancelable, Clear

Dia.ts runs 54,000+ RPS — but performance is the result, not the purpose.

Core principles:

  • 🧠 CancelableTask<T> model: every request is interruptible
  • 🔁 Middleware is functional: (ctx, next) => task
  • 📦 Locals are immutable: extend context cleanly
  • 🛑 AbortSignal for timeout-aware computation

This isn’t about middleware stacking — this is about intent pipelines.


🧨 No More Backend Theater

We don’t need another Express clone.
We don’t need dynamic scaffolding that decays over time.

We need a backend that reflects how apps actually evolve:

  • 🌐 Real-time logic from the start
  • 🧩 State = Event history, not mutable props
  • 📖 Logic = Structured intents
  • 🛠 DX = Typed. Pure. Predictable.

Dia.ts is not a toolchain. It’s a philosophy.


📊 Benchmarks Are Proof — Not the Point

Yes, we beat Bun + Elysia.

Yes, we use native Node + no magic.

But that’s not why Dia.ts exists.

We didn’t optimize the old model. We rejected it — and rebuilt something better.

It’s fast because it’s pure.

It’s safe because it’s structured.

It matters because it’s different.


🌱 It’s Early — and That’s the Best Part

Dia.ts is still pre-alpha:

  • CLI needs polish
  • Docs are sparse
  • Surface is evolving

But:

  • ✅ The intent engine works
  • ✅ The cancellation model is solid
  • ✅ The vision is sharp

If you’ve ever thought “Why is backend still like this?” — this is your exit.


🛠 Try It (Experimental)

npm install dia-ts
npm install -g tsx
mkdir -p gen && npx dia-ts init --with client
📄 routes/hello.post.ts
import { z } from "zod"

export const api = defineAPI({
  input: z.object({ name: z.string() }),
  async handler({ input }) {
    return { message: `hello ${input.name}` }
  }
})
npx dia-ts generate-client
Enter fullscreen mode Exit fullscreen mode
  • GitHub
  • npm
  • Status: pre-alpha — but the fire is lit 🔥

🔭 A Glimpse at What’s Next

Dia.ts is just the beginning.
One day, it won’t just be a framework — but a language.
A language built not for “general purpose,”
but for Web backend, and nothing else.

Fully typed. Fully cancelable.
No Node. No legacy. Just intent.


🧨 Why “Web-only” Matters

Web backend isn’t a toy problem.
It’s real-time, stateful, cancelable, multi-tenant, and deeply coupled to product UX.

General-purpose languages like Go or Java weren’t designed for that.
They’re great for infra, not interaction.

The truth is: Web deserves its own language.
One built not for threads or goroutines — but for structured intent, timeout-aware flows, and type-safe UX alignment.

Dia.ts isn’t trying to do everything.
It’s doing the only thing that matters now — Web backend, the right way.

Fast. Safe. Intentful.

Welcome to the Dia.ts era.

Top comments (4)

Collapse
 
xwero profile image
david duymelinck

I think you are creating a new Meteor

// server
import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // This is just a simple mock user name
  if (Meteor.users.find().count() === 0) {
    Meteor.users.insert({
      username: 'johndoe',
      email: 'johndoe@example.com',
    });
  }
});

// Define a Meteor method to fetch the user's name
Meteor.methods({
  getUserName() {
    // For simplicity, returning a hardcoded name
    const user = Meteor.users.findOne();  // This will get the first user (you can refine this logic as needed)
    return user ? user.username : 'Guest';
  },
});
// client
import { Template } from 'meteor/templating';
import { Meteor } from 'meteor/meteor';
import './main.html';

Template.body.helpers({
  userName() {
    let name = 'Loading...';
    Meteor.call('getUserName', (error, result) => {
      if (error) {
        name = 'Error fetching name';
      } else {
        name = result;
      }
    });
    return name;
  },
});
Enter fullscreen mode Exit fullscreen mode

Got the code from ChatGPT, I know of the framework but I never used it.

Collapse
 
yukinisihikawa profile image
Yuki Nishikawa

That’s a great comparison — Meteor was definitely ahead of its time in trying to unify the frontend and backend mindset.

Where Dia.ts differs is in the focus:

  • It’s not full-stack or reactive — it’s backend-only, but typed end-to-end.
  • Instead of exposing functions or methods, you declare intents — describing what should happen, not how to fetch data.
  • Everything is cancelable, composable, and timeout-aware — built for modern UX where real-time and control matter.
  • And it’s designed around TypeScript from the ground up — no extra build steps, no magic globals.

In a way, I think Dia.ts is trying to fix what Meteor almost got right — but with the constraints and realities of 2025 in mind.

Thanks for pointing that out — it's a great reference point!

Collapse
 
yukinisihikawa profile image
Yuki Nishikawa

🧠 Why Intent?

REST is flexible — but too flexible.

GraphQL is powerful — but overly generic.

RPC is fast — but hard to scale in product UX terms.

What we actually need are APIs that model what the product wants to happen, not what data it wants to fetch.

That’s what “Intent” is:

A declaration of behavior.

Not an endpoint. Not a resolver. Not a method.

It leads to:

  • Type-safe UX alignment
  • Built-in auditability
  • Auth at the intent level
  • Predictable cancellation & composition

This isn’t about removing complexity.

It’s about shaping it with intent.

Collapse
 
yukinisihikawa profile image
Yuki Nishikawa

🌐 Why Web-only?

Because Web backend isn't just a subset of general backend.

It's a domain of its own — with its own laws.

Go is fast. Rust is precise.

But they don’t understand UX.

Web backend today is:

  • Real-time
  • Client-driven
  • Type-bound to the frontend
  • Shaped by cancelable, user-triggered flows

General-purpose languages weren’t designed for this.

Dia.ts is an experiment. A proposal.

That maybe the Web deserves a language of its own.

Not general-purpose. Just the right-purpose.

More to come.