AXAR AI is a lightweight framework for building production-ready agentic applications using TypeScript. Itβs designed to help you create robust, production-grade LLM-powered apps using familiar coding practicesβno unnecessary abstractions, no steep learning curve.
Most agent frameworks are overcomplicated. And many prioritize flashy demos over practical use, making it harder to debug, iterate, and trust in production. Developers need tools that are simple to work with, reliable, and easy to integrate into existing workflows.
At its core, AXAR is built around code. Writing explicit, structured instructions is the best way to achieve clarity, control, and precisionβqualities that are essential when working in the unpredictable world LLMs.
If youβre building real-world AI applications, AXAR gets out of your way and lets you focus on shipping reliable software.
Here's a minimal example of an AXAR agent:
import { model, systemPrompt, Agent } from '@axarai/axar';
// Define the agent.
@model('openai:gpt-4o-mini')
@systemPrompt('Be concise, reply with one sentence')
export class SimpleAgent extends Agent<string, string> {}
// Run the agent.
async function main() {
const response = await new SimpleAgent().run(
'Where does "hello world" come from?',
);
console.log(response);
}
main().catch(console.error);
-
𧩠Type-first design: Structured, typed inputs and outputs with TypeScript (Zod or @annotations) for predictable and reliable agent workflows.
-
π οΈ Familiar and intuitive: Built on patterns like dependency injection and decorators, so you can use what you already know.
-
ποΈ Explicit control: Define agent behavior, guardrails, and validations directly in code for clarity and maintainability.
-
π Transparent: Includes tools for real-time logging and monitoring, giving you full control and insight into agent operations.
-
πͺΆ Minimalistic: Lightweight minimal design with little to no overhead for your codebase.
-
π Model agnostic: Works with OpenAI, Anthropic, Gemini, and more, with easy extensibility for additional models.
-
π Streamed outputs: Streams LLM responses with built-in validation for fast and accurate results.
Set up a new project and install the required dependencies:
mkdir axar-demo
cd axar-demo
npm init -y
npm i @axarai/axar ts-node typescript
npx tsc --init
Warning
You need to configure your tsconfig.json
file as follows for better compatibility:
{
"compilerOptions": {
"strict": true,
"module": "CommonJS",
"target": "es2020",
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Create a new file text-agent.ts
and add the following code:
import { model, systemPrompt, Agent } from '@axarai/axar';
@model('openai:gpt-4o-mini')
@systemPrompt('Be concise, reply with one sentence')
class TextAgent extends Agent<string, string> {}
(async () => {
const response = await new TextAgent().run('Who invented the internet?');
console.log(response);
})();
export OPENAI_API_KEY="sk-proj-YOUR-API-KEY"
npx ts-node text-agent.ts
Warning
AXAR currently requires ts-node because tsx does not yet fully support experimental decorators.
You can easily extend AXAR agents with tools, dynamic prompts, and structured responses to build more robust and flexible agents.
Here's a more complex example (truncated to fit in this README):
// ...
// Define the structured response that the agent will produce.
@schema()
export class SupportResponse {
@property('Human-readable advice to give to the customer.')
support_advice!: string;
@property("Whether to block customer's card.")
block_card!: boolean;
@property('Risk level of query')
@min(0)
@max(1)
risk!: number;
@property("Customer's emotional state")
@optional()
status?: 'Happy' | 'Sad' | 'Neutral';
}
// Define the schema for the parameters used by tools (functions accessible to the agent).
@schema()
class ToolParams {
@property("Customer's name")
customerName!: string;
@property('Whether to include pending transactions')
@optional()
includePending?: boolean;
}
// Specify the AI model used by the agent (e.g., OpenAI GPT-4 mini version).
@model('openai:gpt-4o-mini')
// Provide a system-level prompt to guide the agent's behavior and tone.
@systemPrompt(`
You are a support agent in our bank.
Give the customer support and judge the risk level of their query.
Reply using the customer's name.
`)
// Define the expected output format of the agent.
@output(SupportResponse)
export class SupportAgent extends Agent<string, SupportResponse> {
// Initialize the agent with a customer ID and a DB connection for fetching customer-specific data.
constructor(
private customerId: number,
private db: DatabaseConn,
) {
super();
}
// Provide additional context for the agent about the customer's details.
@systemPrompt()
async getCustomerContext(): Promise<string> {
// Fetch the customer's name from the database and provide it as context.
const name = await this.db.customerName(this.customerId);
return `The customer's name is '${name}'`;
}
// Define a tool (function) accessible to the agent for retrieving the customer's balance.
@tool("Get customer's current balance")
async customerBalance(params: ToolParams): Promise<number> {
// Fetch the customer's balance, optionally including pending transactions.
return this.db.customerBalance(
this.customerId,
params.customerName,
params.includePending ?? true,
);
}
}
async function main() {
// Mock implementation of the database connection for this example.
const db: DatabaseConn = {
async customerName(id: number) {
// Simulate retrieving the customer's name based on their ID.
return 'John';
},
async customerBalance(
id: number,
customerName: string,
includePending: boolean,
) {
// Simulate retrieving the customer's balance with optional pending transactions.
return 123.45;
},
};
// Initialize the support agent with a sample customer ID and the mock database connection.
const agent = new SupportAgent(123, db);
// Run the agent with a sample query to retrieve the customer's balance.
const balanceResult = await agent.run('What is my balance?');
console.log(balanceResult);
// Run the agent with a sample query to block the customer's card.
const cardResult = await agent.run('I just lost my card!');
console.log(cardResult);
}
// Entry point for the application. Log any errors that occur during execution.
main().catch(console.error);
More examples can be found in the examples directory.
- Install dependencies:
npm install
- Build:
npm run build
- Run tests:
npm run test
We welcome contributions from the community. Please see the CONTRIBUTING.md file for more information. We run regular workshops and events to help you get started. Join our Discord to stay in the loop.
AXAR is built on ideas from some of the best tools and frameworks out there. We use Vercel's AI SDK and take inspiration from Pydantic AI and OpenAIβs Swarm. These projects have set the standard for developer-friendly AI tooling, and AXAR builds on that foundation.
Warning
AXAR AI (axar) is currently in early alpha. It is not intended to be used in production as of yet. But we're working hard to get there and we would love your help!