Skip to content

ABC Tool

  • Home
  • About / Contect
    • PRIVACY POLICY
justhamade/triadjs: Triad is a TypeScript/Node.js framework where API specification, implementation, validation, and testing are a single source of truth. · GitHub

justhamade/triadjs: Triad is a TypeScript/Node.js framework where API specification, implementation, validation, and testing are a single source of truth. · GitHub

Posted on June 11, 2026June 11, 2026 By safdargal12 No Comments on justhamade/triadjs: Triad is a TypeScript/Node.js framework where API specification, implementation, validation, and testing are a single source of truth. · GitHub
Blog


One TypeScript definition. Validation, OpenAPI, AsyncAPI, BDD tests, Gherkin, and database schemas — all generated from the same source of truth.

Triad is a TypeScript-first API framework built on the idea that an API’s specification, implementation, validation, and tests should never drift apart, because they are the same thing. You write TypeScript once using Triad’s declarative DSL, and you get:

  • Runtime validation at the edges (parse + reject with structured errors)
  • Static types derived from the same schemas (t.infer<typeof X>)
  • OpenAPI 3.1 documentation for HTTP endpoints
  • AsyncAPI 3.0 documentation for WebSocket channels
  • Executable BDD scenarios that run as tests (triad test)
  • Automatic adversarial tests derived from your schema constraints (scenario.auto())
  • Gherkin .feature files generated for non-technical stakeholders
  • Typed frontend hooks for React Query, Solid Query, Vue Query, Svelte Query (triad frontend generate)
  • Database schemas via a dialect-neutral Drizzle bridge (triad db generate)

No codegen round-trips. No hand-maintained OpenAPI YAML. No duplicate Zod + OpenAPI + test-fixture schemas that fall out of sync.

Triad’s north star is that an AI coding assistant should be able to understand an entire API by reading one place. When schemas, handlers, responses, channel payloads, tests, and docs all live in the same typed definitions, an LLM (or a new engineer) doesn’t have to stitch context together from a Zod file, an OpenAPI YAML, a separate test fixture, and a README that’s three commits out of date. There is one source of truth, and every other artifact is a deterministic projection of it. That’s what keeps humans productive — and it’s what lets AI reason about your API without guessing.


Get started with Claude Code

This repo doubles as a Claude Code marketplace, so the fastest path to a working TriadJS backend is to let Claude do the scaffolding.

1. Add the TriadJS marketplace and install the plugin (one time, in any Claude Code session):

/plugin marketplace add justhamade/triad
/plugin install triadjs@triadjs

This installs 10 skills (schema DSL, endpoints, channels, BDD behaviors with the authoritative assertion phrase table, testing, adapters, Drizzle, CLI, DI) and 8 slash commands (/triadjs:new, /triadjs:model, /triadjs:endpoint, /triadjs:channel, /triadjs:scenario, /triadjs:test, /triadjs:docs, /triadjs:validate).

2. Scaffold your first project:

/triadjs:new a petstore API with pets, adoptions, and a chat room channel

Claude will create the full project layout — package.json, triad.config.ts, schemas, endpoints with behaviors, a Fastify server, and a test setup — then run triad test to confirm every scenario passes. Run npm run dev and Swagger UI is immediately live at http://localhost:3000/api-docs with the live OpenAPI spec at /api-docs/openapi.json. No extra step.

3. Iterate:

/triadjs:endpoint add a soft-delete endpoint for pets
/triadjs:scenario cover the 404 case on getPet
/triadjs:test
/triadjs:docs

Each command loads only the skills it needs, writes idiomatic TriadJS code that matches the phrase table the parser expects, and verifies its own output. See plugin/README.md for the full skill and command catalog.

Don’t use Claude Code? Skip to Taste of it below for a plain-TypeScript walkthrough, or the full Quickstart.


import { t, endpoint, scenario, createRouter } from '@triadjs/core';

const Pet = t.model('Pet', {
  id: t.string().format('uuid').identity(),
  name: t.string().minLength(1).example('Buddy'),
  species: t.enum('dog', 'cat', 'bird', 'fish'),
  age: t.int32().min(0).max(100),
});

const CreatePet = Pet.pick('name', 'species', 'age').named('CreatePet');

const createPet = endpoint({
  method: 'POST',
  path: '/pets',
  summary: 'Create a pet',
  body: CreatePet,
  responses: { 201: Pet, 400: ApiError },
  handler: async (ctx) => {
    const pet = await ctx.services.petRepo.create(ctx.body);
    return ctx.respond[201](pet);
  },
  behaviors: [
    scenario('creates a pet with valid input')
      .when('POST /pets', { body: { name: 'Rex', species: 'dog', age: 3 } })
      .then('status is 201')
      .and('response body matches { name: "Rex", species: "dog" }'),

    // One line — the framework generates ~20 boundary/adversarial
    // tests from the schema constraints you already declared above.
    ...scenario.auto(),
  ],
});

const router = createRouter({ title: 'Petstore', version: '1.0.0' });
router.add(createPet);

From this single file:

  • triad test runs your hand-written scenario AND the auto-generated boundary tests
  • triad fuzz generates adversarial tests for every endpoint without touching any file
  • triad docs emits openapi.yaml
  • triad gherkin emits features/pets.feature
  • triad frontend generate emits typed React/Solid/Vue/Svelte Query hooks
  • ctx.body is fully typed — { name: string; species: 'dog' | 'cat' | ... }

scenario.auto() reads minLength(1), max(100), enum('dog', 'cat') and generates missing-field, boundary-value, invalid-enum, type-confusion, and random-fuzzing scenarios automatically. You write the business logic tests; the framework generates the boundary tests.

For WebSocket channels, channel() works the same way and produces AsyncAPI + typed client libraries.


Package Purpose
@triadjs/core Schema DSL, endpoint(), channel(), scenario(), scenario.auto(), createRouter()
@triadjs/openapi Router → OpenAPI 3.1 (YAML/JSON)
@triadjs/asyncapi Router → AsyncAPI 3.0 (YAML/JSON)
@triadjs/gherkin Behaviors → .feature files
@triadjs/test-runner In-process BDD runner + schema-derived auto-scenario generation
@triadjs/fastify Fastify HTTP + WebSocket adapter
@triadjs/express Express HTTP adapter
@triadjs/hono Hono adapter (Node, Deno, Bun, Cloudflare Workers)
@triadjs/lambda AWS Lambda adapter (API Gateway v1/v2, ALB, Function URL)
@triadjs/drizzle Triad schemas → Drizzle tables + SQL migrations (SQLite, Postgres, MySQL)
@triadjs/tanstack-query Router → typed React Query hooks
@triadjs/solid-query Router → typed Solid Query hooks
@triadjs/vue-query Router → typed Vue Query composables
@triadjs/svelte-query Router → typed Svelte Query store factories
@triadjs/channel-client Router → typed WebSocket clients (vanilla TS, React, Solid, Vue, Svelte)
@triadjs/forms Router → form validators (react-hook-form, @tanstack/form)
@triadjs/jwt requireJWT BeforeHandler factory wrapping jose
@triadjs/otel OpenTelemetry tracing (opt-in router wrapper)
@triadjs/metrics Prometheus metrics (opt-in router wrapper)
@triadjs/logging Structured logging with AsyncLocalStorage (opt-in router wrapper)
@triadjs/security-headers Security headers middleware (Fastify, Express, Hono)
@triadjs/cli triad test, triad fuzz, triad docs, triad new, triad mock, triad db, triad validate, triad frontend


Start at the docs index — it points at everything below based on what you’re trying to do.

Learn by building

  • Tutorial — Build the “Bookshelf” app from hello-world to production-ready in 7 steps

Pick your stack

Work with AI

Reference

Project

Four reference implementations live under examples/ — petstore (Fastify + channels), tasktracker (Express + auth + pagination), bookshelf (all features combined — the tutorial’s final state), and supabase-edge (Hono + Supabase + Deno edge deployment). Each has both in-process behavior tests and real HTTP/WebSocket e2e tests.


Triad is pre-1.0 and under active development. Feature-complete through Phase 26:

  • ✅ Schema DSL with full DDD composition (t.model, t.value, t.file, 14 primitive types)
  • ✅ Endpoint + router + beforeHandler auth extension + checkOwnership helper
  • ✅ scenario.auto() — schema-derived adversarial test generation (missing fields, boundary values, type confusion, random fuzzing)
  • ✅ OpenAPI 3.1 + AsyncAPI 3.0 generators
  • ✅ Gherkin generator (HTTP + channels)
  • ✅ In-process BDD test runner + triad fuzz CLI fuzzer + triad validate --coverage linter
  • ✅ Four HTTP adapters: Fastify (+ channels), Express, Hono (edge runtimes), Lambda (AWS)
  • ✅ Drizzle bridge with SQL migration codegen (SQLite, Postgres, MySQL)
  • ✅ Frontend codegen: TanStack Query, Solid Query, Vue Query, Svelte Query, form validators, typed WebSocket clients
  • ✅ Observability: OpenTelemetry tracing, Prometheus metrics, structured logging (all opt-in router wrappers)
  • ✅ Auth: @triadjs/jwt with JWKS/HS256 + security headers middleware
  • ✅ Developer tooling: triad new scaffolding, triad mock server, triad docs check breaking-change detection

21 packages, 4 reference examples, 83 behavior scenarios, 1000+ unit/integration/property tests. APIs may still shift before 1.0 — pin exact versions if you adopt early.

See ROADMAP.md for phase-by-phase detail.


Most TypeScript API stacks stitch together four or five libraries to get what Triad gives you in one:

Need Typical stack Triad
Runtime validation Zod / Yup t.model()
Static types z.infer<> t.infer<>
OpenAPI zod-to-openapi + hand edits triad docs
BDD tests Cucumber + step defs + fixtures scenario().when().then()
Boundary/fuzz tests Schemathesis (external, Python) scenario.auto() (built-in, zero-config)
Frontend hooks hand-written fetch wrappers triad frontend generate
WebSocket clients hand-written WS wrappers triad frontend generate --target channel-client-react
WebSocket docs hand-written AsyncAPI triad docs
DB schema Drizzle (separate definitions) triad db generate
Breaking-change detection manual OpenAPI diff triad docs check

The point isn’t just fewer dependencies — it’s that a change to a schema is impossible to forget to propagate, because there is nothing to propagate to. And the boundary tests you’d never think to write? The framework writes them for you from the constraints you already declared.


MIT



Source link

Post Views: 1

Post navigation

❮ Previous Post: YouTube and FIFA Expand World Cup Partnership With Inaugural Creator Cup Match
Next Post: Apple’s new Siri AI knows when to shut up ❯

You may also like

Voice AI in India is hard. Wispr Flow is betting on it anyway.
Blog
Voice AI in India is hard. Wispr Flow is betting on it anyway.
May 10, 2026
Gemini Live’s new interactive bar reportedly waves back at users
Blog
Gemini Live’s new interactive bar reportedly waves back at users
May 15, 2026
The Nintendo Switch 2 is getting more expensive later this year
Blog
The Nintendo Switch 2 is getting more expensive later this year
May 10, 2026
Rocket Report: Blue Origin explosion still making headlines; Impulse raises money
Blog
Rocket Report: Blue Origin explosion still making headlines; Impulse raises money
June 7, 2026

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • We managed to glean some interesting details about the Artemis III mission
  • Anthropic’s Dario Amodei has just one direct report
  • Apple’s new Siri AI knows when to shut up
  • justhamade/triadjs: Triad is a TypeScript/Node.js framework where API specification, implementation, validation, and testing are a single source of truth. · GitHub
  • YouTube and FIFA Expand World Cup Partnership With Inaugural Creator Cup Match

Recent Comments

  1. Last Chance for Big Savings on TechCrunch Disrupt 2026 Tickets – Artiverse on 5 days left: Save up to $410 on Disrupt 2026 passes

Archives

  • June 2026
  • May 2026
  • April 2026

Categories

  • Blog

Copyright © 2026 ABC Tool.

Theme: Oceanly News by ScriptsTown