Modular TypeScriptDeveloper Beta
building blocks

Libraries that bundle database schemas, backend routes, and frontend hooks into one package.

Billing

Stripe Billing

Stripe Checkout, webhooks, and subscription management.

  • Keep track of subscriptions status in your database.
  • Webhook handlers included.
  • Hooks for creating/cancelling/upgrading subscription plans.

Install

npm install @fragno-dev/stripe

Auth

Authentication

Coming soon

File Uploads

File Uploads

Coming soon

Frameworks

These frameworks and more are already supported

React
Vue
Svelte
SolidJS
Astro
Next.js
Nuxt
Node.js
Go to Docs

Join the Community

Connect with other developers and stay updated with the latest news

Discord

Join the conversation

Connect with the community, get help with your projects, and stay updated on the latest features and releases.

Join Discord

Newsletter

Get email updates

Receive notifications about new features, releases, and important announcements.

Built on Fragno

A toolkit for building full-stack libraries that integrate into any stack.

Ship the next with Fragno

DatabaseDefine schemas, query with type safety, and write directly to the user's database.
schema("chat", (s) => {  return s.addTable("conversation", (t) => {    return t      .addColumn("id", idColumn())      .addColumn("messages", column("json"))      .addColumn("createdAt", column("timestamp"));  });});
BackendAPI routes are the central abstraction, with input validation included.
defineRoute({  method: "POST",  path: "/chat/:id",  handler: async ({ input }, { json }) => {    return json({      response: generate(input.prompt),    });  },});
FrontendHooks are derived from backend routes for all frontend frameworks.
return {  useChat: b.createMutator("POST", "/chat/:id"),};
FragmentIntegration becomes as simple as using a hook.
const { mutate, loading, error } = useChat();const { response } = await mutate({  body: { prompt },});
Example code

When to use Fragno

More than an API client

Full-stack SDKs

Most SDKs simply wrap API calls. Developers still have to write things like webhook handlers that persist events or build their own frontend hooks.

With Fragno you can ship a pre-built integration for your product.

Do not repeat yourself

Full-stack Components

Build components that can be reused across applications regardless of their stack.

Use community-made Fragments like the Stripe Fragment to add functionality you don't want to maintain yourself.

Framework-agnostic

Works with React, Vue, Svelte, Solid and related full-stack frameworks.

End-to-end type safety

From server to client to database, everything is typed.

Automatic code splitting

Server code never reaches the client bundle.

Built-in state management

Reactive stores with caching built in.

Streaming support

Real-time NDJSON streaming for live data.

Middleware support

Compose auth and custom request processing.

Database Layer

Database-Agnostic Data Persistence

Define schemas, query with type safety, and write directly to the user's database

Define Your Schema

Type-safe tables with automatic migrations and support for indexes and relations

import { schema, idColumn, column }  from "@fragno-dev/db/schema";export const commentSchema = schema("comment", (s) => {  return s    .addTable("comment", (t) => {      return t        .addColumn("id", idColumn())        .addColumn("content", column("string"))        .addColumn("userId", column("string"))        .addColumn("postId", column("string"))        .addColumn(          "createdAt",          column("timestamp")            .defaultTo((b) => b.now())        )        .createIndex("idx_post", ["postId"]);    })    .addTable("user", (t) => {      return t        .addColumn("id", idColumn())        .addColumn("name", column("string"));    })    .addReference("author", {      type: "one",      from: { table: "comment", column: "userId" },      to: { table: "user", column: "id" }    });});

Query with Type Safety

Joins, filtering, and cursor-based pagination

// Find comments with author dataconst comments = await orm.find(  "comment",  (b) =>    b      .whereIndex("idx_post", (eb) =>        eb("postId", "=", postId)      )      .orderByIndex("idx_created", "desc")      .join((j) =>        j.author((authorBuilder) =>          authorBuilder.select(["name"])        )      )      .pageSize(20));// Fully typed resultsfor (const comment of comments) {  console.log(comment.content);  console.log(comment.author?.name);  //                     ^? { name: string } | null}

Atomic Transactions

Optimistic concurrency control with version checking

const uow = orm.createUnitOfWork();// Phase 1: Retrieve with version infouow.find("user", (b) =>  b.whereIndex("primary", (eb) =>    eb("id", "=", userId)  ));const [users] = await uow.executeRetrieve();// Phase 2: Update with optimistic lockconst user = users[0];uow.update("user", user.id, (b) =>  b    .set({ balance: user.balance + 100 })    .check() // Fails if version changed);const { success } = await uow.executeMutations();if (!success) {  // Concurrent modification detected  console.error("Retry transaction");}

Test Everything

In-memory database for fast tests

import { buildDatabaseFragmentsTest }  from "@fragno-dev/test";import { instantiate } from "@fragno-dev/core";describe("auth fragment", async () => {  const { fragments, test } =    await buildDatabaseFragmentsTest()      .withTestAdapter({ type: "drizzle-sqlite" })      .withFragment("auth",        instantiate(authFragmentDefinition)          .withRoutes(routes)          .withConfig({}),      )      .build();  afterAll(async () => {    await test.cleanup();  });  it("creates user and session", async () => {    const response = await fragments.auth.callRoute(      "POST",      "/signup",      {        body: {          email: "test@test.com",          password: "password"        }      }    );    expect(response.data).toMatchObject({      sessionId: expect.any(String),      userId: expect.any(String)    });  });});
Integrates with
Kysely,
Drizzle
&
Prisma

Documentation

Choose your path based on whether you're a user or a library author