Dev Log
Why We're Building an AI Agent Framework in TypeScript
The AI agent tooling ecosystem is dominated by Python. But production applications are TypeScript. We think that mismatch has a real cost, and we built something to close it.
Here is the question we kept asking ourselves last year: why do developers have to write their AI logic in Python and their application logic in TypeScript?
It is not a rhetorical question. There are real, historical reasons the AI tooling ecosystem landed in Python. NumPy, PyTorch, Hugging Face — the research stack is Python, so the early tooling was Python, so the tutorials were Python, and here we are. LangChain, CrewAI, AutoGen. All Python-first.
But the applications that users actually touch? Mostly TypeScript. Next.js. Node. React. The gap between “where AI tooling lives” and “where production apps live” has become something developers paper over with microservices, REST wrappers, and a lot of context-switching.
We think that has a real cost.
The Production Reality
A typical setup we have seen from teams reaching out to us: Python FastAPI service handling the agent/RAG logic, Next.js frontend calling it over HTTP, separate deployment pipelines, type definitions duplicated in both languages, and debugging that crosses two runtimes.
This is not a complaint about Python. Python is the right language for ML research. Training loops, tensor ops, model fine-tuning — none of that should move to TypeScript. But running an agent that calls tools, retrieves context, and returns a structured response to a web app? That is application logic. It belongs where the application lives.
The stack tax is real: two languages, two type systems, two deployment targets, two sets of dependencies to audit.
What Already Exists
Mastra is the closest thing to what we are building. They are TypeScript-first, they came out of the team that built Gatsby, and they have 22k+ GitHub stars and $13M in seed funding. We respect what they are doing. They validated the market.
Vercel AI SDK is excellent for streaming LLM responses in Next.js apps. It handles model routing across 40+ providers cleanly. But RAG in the AI SDK is bolt-on: you bring your own vector store, your own embedding pipeline, your own chunking logic. The framework does not have opinions about how your data gets in or stays fresh.
That is where we think there is space.
RAG-Native, Not RAG-Adjacent
The core bet we are making: RAG should be a first-class primitive in the framework, not a tutorial you follow to wire three separate services together.
When you use Schift, you do not configure a vector store, pick an embedding model, set up a chunking strategy, and then connect it to your agent. You point the agent at a bucket and it works.
import { Agent, RAG } from '@schift-io/sdk';
const agent = new Agent({ name: 'support-bot', rag: new RAG({ bucket: 'docs' }), model: 'claude-sonnet-4-20250514',});
const response = await agent.run('How do I migrate embeddings?');That is the full setup. The RAG layer handles embedding, retrieval, and context assembly. The agent handles tool use, memory, and response generation. You write the application.
The retrieval is backed by our engine, written in Rust, which does sub-300 microsecond vector search at the p99. We built it because we needed something we could self-host with predictable latency, and the off-the-shelf options were not there. We are not publishing benchmark comparisons today — the methodology needs more rigor — but the number that matters for interactive agent use cases is time-to-first-token, and retrieval latency is a significant part of that.
Data Sovereignty as a Design Constraint
One thing we kept hearing from enterprise developers: “We like the managed offering, but we need to know where the data goes.”
This matters more for agents than for generic LLM calls. An agent with RAG access to your internal documentation, your support tickets, your product specs — that data leaving your control is a different category of risk than a one-off completion request.
Our framework is designed to self-host from the start. The execution pipeline is open source. If you want to run the full stack on your own infrastructure, you can. We provide Terraform configs for it. Most teams use our managed cloud because the ops overhead of running vector infra is not something they want, but the option being real changes the trust conversation.
Getting Started
We scaffolded the first template around a customer support chatbot because it is the most common first use case we see and because we dogfood it on schift.io itself.
npx create-schift@latest my-agent --template cs-chatbotThat gives you a Next.js app with a Schift agent wired up, a local dev environment that mirrors production, and a schift deploy command that pushes your app while keeping the execution layer on our end.
The SDK is at @schift-io/sdk on npm. The framework source is open source under Apache 2.0.
What We Are Not Claiming
We are not saying Python agent frameworks are wrong. LangChain and CrewAI are doing serious work and they have much larger ecosystems than we do right now.
We are saying that if you are building a production TypeScript application and you want to add agent capabilities, you should not have to introduce a second language and a second deployment target to do it.
That is the problem we are solving. Everything else follows from there.
What Comes Next
We are working on the full framework documentation and additional templates. The next one after the CS chatbot is a legal-QA agent, because we have several teams using Schift for that use case already and the patterns are worth codifying.
If you are building something with TypeScript agents and you want to compare notes, we are genuinely interested. The hard problems in this space are not the LLM calls — those are solved. They are data ingestion quality, context assembly, and memory. Those are the things we are focused on.
Try the framework: npx create-schift@latest — SDK docs at schift.io/docs