Skip to content

COBALT — GraphQL from TypeScript, without writing GraphQL

The Power of GraphQL, without ``GraphQL``.
The last framework that actually makes sense, in the age of AI.

Explorer
PROJECT
server
operations
post.ts
Query
comment.ts
Mutation
types
Post.ts
Type
ctx.ts
Context
operations/comment.ts
1export function Mutation(postId: string, content: string) {
2 const { prisma } = $$ctx(this);
3 return await prisma.comment.create({
4 data: { postId, content },
5 });
6}

Why Cobalt?
It's simple and powerful.

Cobalt never gets in your way.
It extends GraphQL but doesn't force you to use it manually.

Why not REST?

Endpoint Fatigue & Over-fetching

Managing hundreds of endpoints creates a maintenance nightmare. You fetch huge JSON blobs just to display a username.

The Cobalt Solution

One smart endpoint. The client specifies exactly what data it needs. The GraphQL feature everyone loves.

GET /api/users/1
GET /api/users/1/posts
GET /api/posts/99/comments
GET /api/users/1?include=profile
GET /api/profiles/1/roles
GET /api/roles/1/permissions
250kb Payload
Actual data needed

Why not pure GraphQL?

The Double Declaration Problem

You write a TypeScript interface. Then you write a GraphQL Schema. Then you write a Resolver. If they drift, your app crashes.

The Cobalt Solution

Single source of truth. Your TypeScript code IS your schema. No client-side codegen steps or schema sync required.

Schema.gql
Type.ts
userPostsQuery.gql
types/userPosts.ts
postFragments.gql
postsWithCommentsQuery.gql
types/postsWithComments.ts
commentsQuery.gql
types/comments.ts

Why not tRPC?

Tight Coupling Trap

Great for monoliths, but your backend logic leaks into your client bundle. Scaling to microservices or exposing a public API later becomes a rewrite.

The Cobalt Solution

Loose coupling, magnetic types. The schema is the contract. You can move fast AND scale to complex backends.

trpcClient.user.byId.query(1)
trpcClient.user.byIdWithPosts.query(1)
trpcClient.user.getProfile.query(1)
Client
Server
Tightly Coupled

The Cobalt Way

Magnetic Type Safety

Define your logic once. The Schema is inferred. The SDK is generated. The types are magnetically bonded across the network boundary.

The Cobalt Solution

The best of all worlds. The speed of tRPC, the flexibility of GraphQL, and the simplicity of REST.

// ... resolver logic
  return{
  user:{ id, name, email }
  };
}
Network Boundary
Frontend SDK
const{user}=awaitsdk.query.user(...);
const{id, name, email}=user;

Hate Typing?
Thirsty LLM?

Less is more.
A codebase that is fun to work with.

No Boilerplate

Stop writing glue code

Traditional frameworks require Controllers, manual serialization, and Service layers just to move data.

The Cobalt Solution

Write your logic. Cobalt generates the transport layer. No routers, no adapters, no manual schemas.

Traditional
Router
Controller
Service
Cobalt
server/users.ts
Logic Only

LLM Friendly

Context Rot

LLMs struggle with large, scattered codebases. Providing context across 50 files degrades performance and increases cost.

The Cobalt Solution

Dense, collocated code. Smaller context window footprint means smarter AI assistance and lower token costs.

Typical App Context11.2k Tokens
45 Files (DTOs, Types, Resolvers, Services...)
Cobalt App Context3.4k Tokens
13 Files (Schema-inferred Resolvers)

Zero-Config SDK

Typed SDKs for free

Writing GraphQL queries manually is tedious and error-prone. Cobalt gives you a fully typed SDK out of the box.

The Cobalt Solution

sdk.query.user({ id })() - Autocomplete your entire backend, as if it was local code. No graphql tags, no codegen watchers.

Use GraphQL selections only if you want to.

Simple Mode (default)
constuser=awaitsdk.query.user({ id: "1" })();
// Returns full object automatically
With Sub-Selection
constuser=awaitsdk.query.user({ id: "1" })(({
id, name, avatar
}) => ({
id, name, avatar
}));
// Returns only requested fields

START WITH COBALT

Join the developers building the next generation of type-safe APIs.

Open source. Fast. Magnetic.