A lightweight, Rails-inspired web framework for Crystal. Build fast, type-safe APIs with minimal boilerplate.
- 🚀 Fast CLI - Generate apps, models, controllers, and more
- 🎨 Beautiful ASCII Banners - Dynamic command banners for every command
- 🗄️ Database Migrations - SQLite-based migrations with automatic timestamps
- 🔐 Built-in Authentication - JWT-based auth with password hashing
- 📦 Scaffold Generator - Full CRUD scaffolding with one command
- 🛣️ Route Management - Simple DSL for defining routes
- 📊 Interactive Console - Explore your data with an interactive REPL
- 🎯 Type-Safe - Full Crystal type safety throughout
- Crystal 1.0 or higher
- SQLite3 (for database)
# Clone the repository
git clone https://github.com/backlinkedclub/kothari_api.git
cd kothari_api
# Install dependencies
shards install
# Build the CLI
crystal build src/cli/kothari.cr -o kothari
# Install globally (optional)
sudo mv kothari /usr/local/bin/kothari# Create a new app
kothari new myapp
cd myapp
# Install dependencies
shards install
# Generate a scaffold
kothari g scaffold post title:string content:text
# Run migrations
kothari db:migrate
# Start the server
kothari serverVisit http://localhost:3000/posts to see your API in action!
Creates a new KothariAPI application with the standard directory structure.
kothari new blog_api
cd blog_api
shards installGenerated Structure:
myapp/
├── app/
│ ├── controllers/
│ └── models/
├── config/
│ └── routes.cr
├── db/
│ └── migrations/
├── src/
│ └── server.cr
└── shard.yml
Starts the development server. Default port is 3000.
# Default port (3000)
kothari server
# Custom port
kothari server -p 3001
kothari server --port 5000Compiles your application into a binary.
# Build with default name
kothari build
# Build with custom name
kothari build myapp
# Build optimized release
kothari build myapp --releaseGenerates a new model with optional fields.
# Simple model
kothari g model user
# Model with fields
kothari g model article title:string content:text views:integerSupported Data Types:
string,text→Stringint,integer→Int32bigint,int64→Int64float,double→Float64bool,boolean→Booljson,json::any→JSON::Anytime,datetime,timestamp→Timeuuid→String
Generates a database migration.
kothari g migration create_users email:string password_digest:string
kothari db:migrateGenerates a new controller with an index action and route.
kothari g controller blog
# Creates BlogController with GET /blog routeGenerates a complete CRUD scaffold: model, migration, controller, and routes.
# Generate scaffold
kothari g scaffold post title:string content:text published:bool
# Run migrations
kothari db:migrate
# Start server
kothari serverGenerated Routes:
GET /posts- List all postsPOST /posts- Create a new postGET /posts/:id- Show a postPATCH /posts/:id- Update a postDELETE /posts/:id- Delete a post
Generates authentication system with User model, AuthController, and routes.
kothari g auth
kothari db:migrateGenerated Routes:
POST /signup- Register a new userPOST /login- Authenticate and get JWT token
Example Usage:
# Signup
curl -X POST http://localhost:3000/signup \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secure123"}'
# Login
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"secure123"}'Runs all pending database migrations.
kothari db:migrateDrops the database, recreates it, and runs all migrations.
kothari db:resetLists all registered routes in a formatted table.
kothari routesOutput:
╔═══════════════════════════════════════════════════════════╗
║ ROUTES TABLE ║
╚═══════════════════════════════════════════════════════════╝
Method Path Controller#Action
------------------------------------------------------------
GET / home#index
GET /posts posts#index
POST /posts posts#create
POST /signup auth#signup
POST /login auth#login
Total: 5 route(s)
Opens an interactive console for exploring your models and running SQL queries.
kothari consoleConsole Commands:
# List all models
models
# Query models
Post.all
Post.find(1)
Post.where("title = 'Hello'")
# Run SQL
sql SELECT * FROM posts
# Exit
exitDisplays the help menu with all available commands.
kothari
kothari helpmyapp/
├── app/
│ ├── controllers/ # Application controllers
│ │ ├── home_controller.cr
│ │ └── posts_controller.cr
│ ├── models/ # Data models
│ │ └── post.cr
│ ├── controllers.cr # Auto-loader for controllers
│ └── models.cr # Auto-loader for models
├── config/
│ └── routes.cr # Route definitions
├── db/
│ ├── migrations/ # Database migrations
│ └── development.sqlite3 # SQLite database
├── src/
│ └── server.cr # HTTP server entry point
├── shard.yml # Dependencies
└── console.cr # Console entry point
Define routes in config/routes.cr:
KothariAPI::Router::Router.draw do |r|
r.get "/", to: "home#index"
r.get "/posts", to: "posts#index"
r.post "/posts", to: "posts#create"
r.get "/posts/:id", to: "posts#show"
endControllers inherit from KothariAPI::Controller:
class PostsController < KothariAPI::Controller
def index
json(Post.all)
end
def create
attrs = post_params
post = Post.create(
title: attrs["title"].to_s,
content: attrs["content"].to_s
)
context.response.status = HTTP::Status::CREATED
json(post)
end
private def post_params
JSON.parse(context.request.body.not_nil!.gets_to_end).as_h
end
end
KothariAPI::ControllerRegistry.register("posts", PostsController)Models inherit from KothariAPI::Model:
class Post < KothariAPI::Model
table "posts"
@title : String
@content : String
@created_at : String?
@updated_at : String?
def initialize(@title : String, @content : String,
@created_at : String? = nil, @updated_at : String? = nil)
end
KothariAPI::ModelRegistry.register("post", Post)
endModel Methods:
Post.all- Get all recordsPost.find(id)- Find by IDPost.create(**fields)- Create a new recordPost.where(condition)- Query with SQL condition
KothariAPI supports the following data types:
| CLI Type | Crystal Type | SQL Type | Example |
|---|---|---|---|
string, text |
String |
TEXT |
name:string |
int, integer |
Int32 |
INTEGER |
age:int |
bigint, int64 |
Int64 |
INTEGER |
views:bigint |
float, double |
Float64 |
REAL |
price:float |
bool, boolean |
Bool |
INTEGER |
active:bool |
json, json::any |
JSON::Any |
TEXT |
metadata:json |
time, datetime, timestamp |
Time |
TEXT |
created:time |
uuid |
String |
TEXT |
id:uuid |
KothariAPI includes built-in JWT-based authentication:
# Generate auth
kothari g auth
kothari db:migrateUsage:
# Signup
POST /signup
{
"email": "user@example.com",
"password": "password123"
}
# Login (returns JWT token)
POST /login
{
"email": "user@example.com",
"password": "password123"
}Every command displays a beautiful ASCII art banner with the command name:
kothari new myapp # Shows "NEW" banner
kothari db:migrate # Shows "MIGRATE" banner
kothari routes # Shows "ROUTES" banner
kothari help # Shows "HELP" banner# Create app
kothari new blog_api
cd blog_api
shards install
# Generate scaffold
kothari g scaffold post title:string content:text published:bool
# Generate auth
kothari g auth
# Run migrations
kothari db:migrate
# Start server
kothari server -p 3000API Endpoints:
GET /posts- List all postsPOST /posts- Create a postPOST /signup- Register userPOST /login- Login user
kothari new shop_api
cd shop_api
shards install
# Products with JSON metadata
kothari g scaffold product \
name:string \
price:float \
metadata:json \
created:time
kothari db:migrate
kothari server# Build the framework
crystal build src/cli/kothari.cr -o kothari
# Test in a new app
kothari new test_app
cd test_app
shards install
kothari server- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE file for details
- GitHub Issues: https://github.com/backlinkedclub/kothari_api/issues
- Documentation: See this README
Current Version: 1.0.0
Built with ❤️ using Crystal