Updated for nself v1.0.12 v1.0.12
Let's build your first ɳSelf project step by step. We'll create a complete backend for a todo application with user authentication, real-time data, and file storage.
In this tutorial, we'll create a backend that includes:
First, create a new directory for your project and navigate to it:
mkdir todo-backend
cd todo-backendInitialize a new ɳSelf project:
nself initYou'll be asked a few questions (or accept defaults):
local.nself.org)What gets created:
todo-backend/
├── .env # Your configuration
├── .env.secrets # Sensitive credentials (auto-generated)
└── ɳSelf/ # Project directoryGenerate the Docker configuration and start services:
nself build # Generate docker-compose.yml, nginx configs, etc.
nself start # Launch all servicesFirst start takes 2-5 minutes (downloading Docker images).
Check status:
nself status # Service health
nself urls # Access URLsɳSelf uses a database-first approach. Create schema.dbml to define your todo application schema:
// Todo Application Schema
Table users {
id uuid [pk, default: `gen_random_uuid()`]
email varchar(255) [unique, not null]
display_name varchar(255)
created_at timestamp [default: `now()`]
updated_at timestamp [default: `now()`]
}
Table todos {
id uuid [pk, default: `gen_random_uuid()`]
user_id uuid [not null, ref: > users.id]
title varchar(255) [not null]
description text
completed boolean [default: false]
due_date timestamp
created_at timestamp [default: `now()`]
updated_at timestamp [default: `now()`]
indexes {
user_id
completed
(user_id, completed) [name: "idx_user_completed"]
}
}
Table todo_attachments {
id uuid [pk, default: `gen_random_uuid()`]
todo_id uuid [not null, ref: > todos.id]
file_url varchar(500) [not null]
file_name varchar(255) [not null]
file_size integer
mime_type varchar(100)
uploaded_at timestamp [default: `now()`]
indexes {
todo_id
}
}Run the migration commands to apply your schema:
nself db migrate # Generate migration from current schema state
nself db update # Apply pending migrations
nself db seed # Seed sample dataThese commands:
Sample users created (local/staging):
admin@example.com (admin role)user@example.com (user role)demo@example.com (viewer role)Trust SSL certificates for HTTPS access:
nself trustYour backend is now running. Access the services:
| Service | URL | Description |
|---|---|---|
| GraphQL API | https://api.local.nself.org | Hasura console + API |
| Auth | https://auth.local.nself.org | Authentication service |
| Admin | https://admin.local.nself.org | Admin dashboard (if enabled) |
https://mail.local.nself.org | Email testing UI (if enabled) |
Open the Hasura Console at https://api.local.nself.org/console and try this GraphQL query:
mutation CreateTodo {
insert_todos_one(object: {
title: "Learn ɳSelf"
description: "Complete the tutorial"
user_id: "00000000-0000-0000-0000-000000000000"
}) {
id
title
created_at
}
}Configure authentication rules in Hasura Console:
{ "user_id": { "_eq": "X-Hasura-User-Id" } }Extend your backend with third-party integrations (112 available — 25 free, 87 paid):
# List available plugins
nself plugin list
# Install free plugins (no key needed)
nself plugin install analytics
# Install Pro plugins (requires active membership)
nself plugin install ai
nself plugin install notifyWhen ready for production:
# Create production environment
nself env create prod production
# Edit server configuration
# .environments/prod/server.json
# Deploy
nself deploy prodYour project structure should now look like:
todo-backend/
├── .env # Main configuration
├── .env.secrets # Sensitive credentials
├── schema.dbml # Your database schema
├── docker-compose.yml # Generated orchestration
├── nginx/ # Reverse proxy configs
├── postgres/ # Database initialization
│ └── migrations/ # SQL migrations
├── ssl/ # SSL certificates
├── services/ # Custom services (if any)
└── ɳSelf/
├── migrations/ # Migration files
├── seeds/ # Seed data files
├── types/ # Generated types
└── backups/ # Database backupsYou've built a complete backend with:
112 plugins available (25 free + 87 paid). Run nself plugin list to browse and nself plugin install <name> to add any plugin to your stack.
Next, explore: