Introduction
Atlantus is a language and runtime for web backends.
You write .atl. You run the atlantus CLI. You do not need to
install Rust or touch the framework source to build APIs.
| You get | Meaning |
|---|---|
| Language | Typed .atl modules under a fixed app/ layout |
| CLI | new, check, dev, start, db, generators |
| Runtime | Long-lived HTTP process (state can survive requests) |
| Views | HTML templates under app/views |
Product cycle
install binary → new project → check → dev → start
- Install
atlantus atlantus new my-apiatlantus checkatlantus devatlantus startfor production-shaped serve
Compared to other stacks
| Stack | Atlantus |
|---|---|
| PHP + FPM | Long-lived atlantus process + .atl handlers |
| Node + Express | Same idea: edit routes, restart/reload, ship one binary runtime |
| Laravel Blade | File views with a small Blade-near syntax |
| Composer / npm | App deps evolving; start with a single binary |
This documentation
| Section | Use when |
|---|---|
| Start here | Install and first API |
| Language | Syntax, HTTP, views, built-ins |
| Framework | DB, auth, jobs, CLI |
| Ship it | Deploy and examples |
Site: atl-docs.atlantus.network.
Next: Install.
Install
You only need the atlantus binary. You do not need Rust, Cargo, or a clone of the framework to create apps and program in .atl.
Recommended: download the release binary
Current product version: 0.2.1
Primary asset (today): Linux x86_64
Option A — GitHub CLI (best for private releases)
gh auth login # once, if needed
gh release download v0.2.1 \
--repo atlantus-network/atlantuslanguage \
--pattern 'atlantus-*' \
--dir /tmp
chmod +x /tmp/atlantus-v0.2.1-linux-x86_64
mkdir -p ~/.local/bin
mv /tmp/atlantus-v0.2.1-linux-x86_64 ~/.local/bin/atlantus
export PATH="$HOME/.local/bin:$PATH"
atlantus --version # → atlantus 0.2.1
Option B — install script (no compile)
If you have the monorepo checked out or a copy of scripts/install-binary.sh:
./scripts/install-binary.sh --tag v0.2.1
# default install: ~/.local/bin/atlantus
export PATH="$HOME/.local/bin:$PATH"
atlantus --version
Private repo download uses gh or GH_TOKEN / ATL_GH_TOKEN.
Option C — manual from the Releases page
- Open the release:
https://github.com/atlantus-network/atlantuslanguage/releases/tag/v0.2.1 - Download
atlantus-v0.2.1-linux-x86_64 - Install:
chmod +x atlantus-v0.2.1-linux-x86_64
sudo mv atlantus-v0.2.1-linux-x86_64 /usr/local/bin/atlantus
# or: mv … ~/.local/bin/atlantus
atlantus --version
Verify
atlantus --help
atlantus --version
You should see a semver like atlantus 0.2.1.
Product cycle (after install)
atlantus new my-api → check → dev → start
Next: Getting started.
Platforms
| Platform | Status (0.2.1) |
|---|---|
| Linux x86_64 | Prebuilt binary on GitHub Releases |
| macOS / Windows / ARM | Not yet as official assets — use Docker or ask for a build |
Docker (optional)
If you prefer containers and never install a host binary, see Deploy.
Build from source (contributors only)
Compiling the CLI does require Rust. That path is for people who develop the runtime itself — not for application authors.
# requires rustup + cargo — contributors only
./scripts/install-from-git.sh --tag v0.2.1 --smoke
App developers should stay on the binary path above.
Getting started (≈10 minutes)
Write backends in .atl. Install only the atlantus binary.
You do not need Rust, Cargo, or the framework monorepo.
0. Prerequisites
- A shell (Linux recommended for the current binary)
curlor GitHub CLI (gh)- A directory on your
PATH(e.g.~/.local/bin)
Optional later: Docker for container deploy.
1. Install atlantus
Full options: Install. Short path:
gh release download v0.2.1 \
--repo atlantus-network/atlantuslanguage \
--pattern 'atlantus-*' \
--dir /tmp
chmod +x /tmp/atlantus-v0.2.1-linux-x86_64
mkdir -p ~/.local/bin
mv /tmp/atlantus-v0.2.1-linux-x86_64 ~/.local/bin/atlantus
export PATH="$HOME/.local/bin:$PATH"
atlantus --version # → atlantus 0.2.1
2. Create a project
atlantus new my-api
cd my-api
Optional auth stubs:
atlantus new my-api --with-auth
Everything you ship lives under app/**/*.atl (plus app/views/**/*.html
for HTML). There is no main.rs in the product path.
3. Check
atlantus check --path .
# often also: atlantus check
4. Dev server
atlantus dev --path . --host 127.0.0.1 --port 3000
# hot reload when editing .atl:
atlantus dev --path . --watch
curl -sS http://127.0.0.1:3000/health
5. Database (when you need it)
Scaffolded apps use SQL migrations under db/migrations/:
export ATL_DATABASE_URL="sqlite:./tmp/app.db?mode=rwc"
atlantus db migrate --path .
atlantus dev --path .
6. Production-shaped start
export ATL_ENV=production
export ATL_AUTH_SECRET='replace-with-a-long-random-secret' # if using auth
export ATL_DATABASE_URL='…'
atlantus start --path . --host 0.0.0.0 --port 3000
Done when
-
atlantus --versionprints a semver -
atlantus newcreated a project -
atlantus checkis green -
curlhits your local server
Next
Troubleshooting (app developers)
| Symptom | Fix |
|---|---|
atlantus: command not found | Install binary; put bin dir on PATH |
| Download 404 / auth error | Private release: gh auth login or GH_TOKEN |
| Wrong OS/arch | 0.2.1 ships linux-x86_64; see Install |
| Port already in use | atlantus dev --port 3001 |
Contributors only
Building the CLI from source needs Rust — see Install → Build from source. App authors should never need that section.
Your first API
Build a small JSON API with only the atlantus CLI.
1. Scaffold
atlantus new hello-api
cd hello-api
2. Add a route module
Create app/routes/hello.atl:
module hello
get "/hello" {
def hello(req) {
return json({ message: "Hello, Atlantus!" })
}
}
get "/hello/{name}" {
def hello_name(req) {
let name = req.param("name")
return json({ message: "Hello, " + name + "!" })
}
}
3. Wire the module
Open the scaffold entry (usually app/main.atl or app/routes/mod.atl) and
import your module the same way other route modules are imported in the
generated tree. If the scaffold already globs routes, a new file under
app/routes/ may be enough — run atlantus check and fix any “unknown module”
diagnostics.
Typical pattern:
import routes.hello
(Exact import syntax follows your generated app/ layout — prefer matching
existing imports in the scaffold.)
4. Run
atlantus check --path .
atlantus dev --path . --port 3000
curl -sS http://127.0.0.1:3000/hello
curl -sS http://127.0.0.1:3000/hello/Ada
5. HTML page (optional)
get "/hi/{name}" {
def hi(req) {
let name = req.param("name")
return view("hello/show", { "name": name })
}
}
app/views/hello/show.html:
@extends("layouts/app")
@section("content")
<h1>Hello, {{ name }}!</h1>
@endsection
See HTML views.
Response helpers
| API | Meaning |
|---|---|
json(body) | HTTP 200 + JSON |
json(body, 201) | Created |
status(204) | No body |
html(body) | HTML string response |
view(path, data) | File template → HTML response |
More: Built-in API.
Checklist
-
atlantus checkgreen - Route listed when
atlantus devstarts -
curlreturns the expected JSON
Next: Project layout.
Project layout
A product app is a directory with atlantus.toml and an app/ tree of .atl
files.
my-api/
atlantus.toml
.vscode/ # VS Code / Cursor: .atl settings, extension tip, tasks
app/
main.atl # entry / composition
routes/ # HTTP handlers (*.atl)
models/
services/
repositories/
jobs/
events/
policies/
providers/
views/ # HTML templates (*.html)
config/ # env / database config (when scaffolded)
db/
migrations/ # SQL migrations
Open the project folder in VS Code or Cursor: install the recommended Atlantus
(.atl) extension when prompted for syntax highlighting. .vscode/settings.json
already associates *.atl and points atl.lsp at the atl-lsp binary if you
have it on PATH.
Rules of thumb
| Path | Role |
|---|---|
app/routes/*.atl | HTTP routes (get / post / …) |
app/services/*.atl | Business logic |
app/models/*.atl | Domain shapes |
app/views/**/*.html | Templates for view(...) |
db/migrations/ | Schema evolution |
atlantus.toml | Project name, server defaults |
No Rust required for handlers. atlantus new creates this tree for you.
Multi-file modules
// app/routes/users.atl
module users
import services.users as Users
get "/users/{id}" {
def show(req) {
return json(Users.find(req.param("id")))
}
}
The compiler loads app/**/*.atl into one module + route table for the runtime.
Environment variables (common)
| Env | Use |
|---|---|
ATL_DATABASE_URL | SQLite / Postgres URL |
ATL_ENV | development / production |
ATL_AUTH_SECRET | Required in production when using auth |
ATL_CORS_ORIGINS | CORS allow list (comma-separated) |
ATL_MAX_BODY_BYTES | Max request body size |
Commands in a project directory
atlantus check --path .
atlantus db migrate --path .
atlantus dev --path . --port 3000
atlantus start --path . --host 0.0.0.0 --port 3000
Next: Syntax.
ATL-S syntax (5 minutes)
Write HTTP apps in short .atl. Sugar expands to the same runtime as classic
forms; older verbose styles still work.
Hello route
module app
get "/hello" {
def hello(req) {
return json({ message: "hi" })
}
}
fn main() -> Int {
return 0
}
atlantus check --path .
Route blocks
get "/users" { def index(req) { return json(list()) } }
get "/users/{id}" { def show(req) { return json(get_one(req.param("id"))) } }
post "/users" { def create(req) { return json(create(req.json()), 201) } }
put "/users/{id}" { def update(req) { return json(update(req.param("id"), req.json())) } }
delete "/users/{id}" { def destroy(req) {
if delete_one(req.param("id")) {
return status(204)
}
return json({ error: "not_found" }, 404)
}}
- One
def/fnper block - Method + path become HTTP routes
- Untyped
reqis the request; omitted return is a response
def and fn
def add(a: Int, b: Int) -> Int {
return a + b
}
fn add(a: Int, b: Int) -> Int {
return a + b
}
JSON responses
| Write this | Means this |
|---|---|
json(body) / ok(body) | HTTP 200 + JSON body |
json(body, 201) / created(body) | HTTP 201 + JSON body |
status(204) / no_content() | Status only |
Request helpers
| Write this | Means this |
|---|---|
req.param("id") | Path param {id} |
req.json() | Parsed JSON body |
req.header("authorization") | Header value |
req.method() / req.path() | Method / path |
Elegant handlers
Short status + early-exit sugar (desugars to the same natives as above):
| Write this | Means this |
|---|---|
not_found(msg?) | 404 error envelope |
unauthorized / forbidden / bad_request | 401 / 403 / 400 |
unprocessable(msg_or_fields?) | 422 validation_failed |
let x = require_found(e, msg?) | value or 404 |
let x = require_json(req) | body or 422 |
let x = require_auth(req) | user id or 401 |
require_fields(map, ["a","b"]) | 422 if missing field |
get "/users/{id}" {
def show(req) {
let user = require_found(db_get("users", req.param("id")), "not found")
return ok(user)
}
}
post "/users" {
def create(req) {
let body = require_json(req)
require_fields(body, ["name"])
return created(body)
}
}
Null checks with none
let user = find(id)
if user is none {
return not_found()
}
return ok(user)
Control flow
if n > 0 {
return ok({ ok: true })
} else if n == 0 {
return ok({ ok: "zero" })
} else {
return bad_request("n must be >= 0")
}
Maps and arrays
let user = { "name": "Ada", "id": 1 }
let tags = ["atl", "web"]
Next: Language overview · HTTP & JSON.
Language overview
Atlantus apps are multi-file .atl modules under app/. The CLI compiles
them and the runtime serves HTTP routes.
What you write
- Functions and route handlers in
.atl - JSON-friendly values: numbers, strings, bools, arrays, maps
- Null checks with
none - Modules with
import
Types (practical)
| Type | Notes |
|---|---|
Int, Float, Bool, String | Scalars |
| Arrays / lists | Ordered values |
Maps / { "k": v } | JSON objects |
| Request / Response | Inferred at the HTTP boundary |
Day to day, rely on atlantus check for type and arity errors.
Modules
module users
import services.users as Users
Paths under app/ map to import paths. Prefer matching the scaffold’s style.
Built-ins
HTTP, request, DB, auth, and jobs helpers are built into the runtime.
See Built-in API.
Dev vs production
| Command | Typical use |
|---|---|
atlantus dev | Fast compile, great DX, optional --watch |
atlantus start | Production-shaped process |
You write the same .atl either way.
How it runs (optional)
Internally the toolchain compiles to bytecode (and may AOT hot paths). You do
not configure compiler crates as an app author — install atlantus and focus on
.atl.
Next: HTTP & JSON.
HTTP & JSON
Returning JSON
get "/health" {
def health(req) {
return ok({ "status": "ok" })
}
}
post "/items" {
def create(req) {
let body = require_json(req)
require_fields(body, ["name"])
return created({ "id": 1, "ok": true })
}
}
json(body) and ok(body) are equivalent (HTTP 200). Prefer created(body)
for 201 and json(body, code) when you need another status.
Status-only
return no_content() // 204
// or: return status(204)
Path params
get "/users/{id}" {
def show(req) {
let id = req.param("id")
return ok({ "id": id })
}
}
Headers
let auth = req.header("authorization")
// or early-exit: let uid = require_auth(req)
Content types
| Helper | Typical Content-Type |
|---|---|
json(...) / ok(...) / created(...) | application/json |
html(...) / view(...) | text/html; charset=utf-8 |
Errors
Unhandled runtime errors become 500 JSON with a request_id. Prefer
explicit helpers (stable error codes):
return not_found()
return not_found("user missing")
return unauthorized()
return forbidden("no access")
return bad_request("bad id")
return unprocessable({ "email": "required" })
These desugar to http_json_response with { error, message? } or
{ error: "validation_failed", fields? }. Classic
json({ "error": "not_found" }, 404) still works.
CORS & body limits
| Env | Meaning |
|---|---|
ATL_CORS_ORIGINS | Comma-separated origins |
ATL_MAX_BODY_BYTES | Max body size (default ~10 MiB) |
Next: HTML views · Natives.
HTML views
File templates under app/views/**/*.html — Blade-near, intentionally small.
API
| API | Meaning |
|---|---|
view(path, data) | Render file → HTML response (200) |
view(path, data, status) | Same with status |
render_view(path, data) | Render → string |
html(body) | HTML response from a string |
render_template(tpl, data) | Inline string template |
Paths are relative to app/views/ ("hello/show" → hello/show.html).
Requires running against a project directory (atlantus dev --path …).
Handler
get "/hello/{name}" {
def hello_name(req) {
let name = req.param("name")
return view("hello/show", { "name": name })
}
}
Template syntax
| Construct | Effect |
|---|---|
{{ key }} | HTML-escaped |
{{{ key }}} | Raw |
{{-- comment --}} | Stripped |
@if(x) / @else / @endif | Conditional |
@foreach(list as item) / @endforeach | Loop |
@extends("layouts/app") | Layout |
@section("content") … @endsection | Section |
@yield("content") | Layout hole |
@include("partials/nav") | Partial |
Layout example
app/views/layouts/app.html:
<!DOCTYPE html>
<html>
<body>
@include("partials/nav")
<main>@yield("content")</main>
</body>
</html>
app/views/hello/show.html:
@extends("layouts/app")
@section("content")
<h1>Hello, {{ name }}!</h1>
@endsection
Principles
- Escape by default
- Views are pure (no DB) — handlers pass data maps
- Prefer file views for real pages
Try it with atlantus dev after adding routes + templates.
Next: Built-in API.
Built-in API (natives)
Handlers call built-in functions provided by the runtime (often called
natives). You do not import crates — if atlantus check accepts the name,
the host implements it.
This page is the practical catalog for app authors. Prefer atlantus check for
arity/type feedback on your version.
HTTP responses
| Call | Result |
|---|---|
json(body) / ok(body) | 200 + JSON body |
json(body, status) | JSON with status (e.g. 201) |
created(body) | 201 + JSON body |
status(code) | Status only (e.g. 204) |
no_content() | 204 status only |
not_found(msg?) | 404 JSON { error: "not_found", message? } |
unauthorized(msg?) | 401 error envelope |
forbidden(msg?) | 403 error envelope |
bad_request(msg?) | 400 error envelope |
unprocessable(msg_or_fields?) | 422 validation_failed |
html(body) | 200 HTML |
html(body, status) | HTML with status |
view(path, data) | Render app/views/... → HTML response |
view(path, data, status) | Same with status |
render_view(path, data) | Render → string |
render_template(tpl, data) | Inline template → string |
Status helpers desugar to http_json_response / http_status — same runtime as
verbose forms.
Request
| Call / sugar | Meaning |
|---|---|
req.param("id") | Path param {id} |
req.json() | Parsed JSON body (or none) |
req.header("authorization") | Header |
req.method() | HTTP method |
req.path() | Path |
Early-exit require helpers
Compiler sugar (expand to bind + early return), not separate host APIs:
| Call / sugar | Meaning |
|---|---|
let x = require_found(expr, msg?) | Value or 404 not_found |
let x = require_json(req) | JSON body or 422 |
let x = require_auth(req) | auth_user_id(req) or 401 |
require_fields(map, ["a","b"]) | Statement; 422 if a field is missing |
Control / null
| Call / sugar | Meaning |
|---|---|
x is none | Null check |
x is not none | Present |
Database (when SQLite/Postgres is enabled)
Exact names follow your CLI version — common pattern in product apps:
| Area | Examples (check with your binary) |
|---|---|
| Query | db_query_one, db_query_all |
| Execute | db_execute |
| Helpers | list/get patterns used after atlantus db migrate |
Always set:
export ATL_DATABASE_URL="sqlite:./tmp/app.db?mode=rwc"
atlantus db migrate --path .
See Database for a minimal flow. For a full working app tree,
atlantus new + migrations is the supported starting point.
Auth (when enabled)
Typical surface (scaffold --with-auth / blog-style apps):
- Password hash / verify natives
- Token or session helpers (
auth_user_id(req)— used byrequire_auth) - Login rate helpers
Production requires:
export ATL_ENV=production
export ATL_AUTH_SECRET='long-random-secret'
See Auth.
Jobs / events
Enqueue-style natives and a worker process for durable work — see Jobs.
Logging
| Call | Meaning |
|---|---|
log_info(...) | Structured/info log (host) |
How to discover more
atlantus check --path .
# type errors name unknown or mis-arity natives
atlantus --help
When something is missing, upgrade the atlantus binary from Releases — do not
install Rust to “get more APIs.”
Database
Use SQL migrations + ATL_DATABASE_URL. Development usually starts with
SQLite; production often uses Postgres.
1. Configure
export ATL_DATABASE_URL="sqlite:./tmp/app.db?mode=rwc"
# production example:
# export ATL_DATABASE_URL="postgres://user:pass@host:5432/dbname"
2. Migrate
atlantus db migrate --path .
Migrations live under db/migrations/ (created by atlantus new or your team’s
templates).
3. From handlers
Use the runtime’s DB built-ins (names validated by atlantus check on your
binary). Pattern:
get "/users/{id}" {
def show(req) {
let id = req.param("id")
let user = /* db_query_one / project helper for users by id */
if user is none {
return json({ "error": "not_found" }, 404)
}
return json(user)
}
}
Prefer putting SQL access in app/repositories/ or app/services/ and keeping
routes thin — that is what atlantus new scaffolds toward.
Checklist
| Step | Command / env |
|---|---|
| URL | ATL_DATABASE_URL |
| Schema | atlantus db migrate --path . |
| Serve | atlantus dev --path . |
Production notes
- Run migrations in deploy before
atlantus start - Do not commit secrets; inject via env
- Prefer Postgres for multi-node
Auth
Atlantus can scaffold auth-oriented routes and uses runtime helpers for passwords and tokens/sessions.
Scaffold
atlantus new my-api --with-auth
cd my-api
Production secret
When ATL_ENV=production, set a strong secret:
export ATL_ENV=production
export ATL_AUTH_SECRET="long-random-secret"
atlantus start --path .
Local dev can omit production env; never ship with a default secret.
Typical routes
Scaffolds and sample apps often expose:
POST /auth/registerPOST /auth/loginGET /me(authenticated)
Open the generated app/routes/ files after --with-auth — that is the
supported copy-paste base.
Practices
- Hash passwords only via runtime helpers (never roll your own)
- Prefer the scaffold’s token/session flow
- Rate-limit login in production when helpers are available
Next: Jobs.
Jobs & queues
Background work is modeled as jobs (and sometimes events). Simple apps may drain work in-process; durable setups run a worker next to HTTP.
Mental model
HTTP handler → enqueue job → worker processes job
When to use a job
| Use a job | Keep in the request |
|---|---|
| Email, webhooks, slow I/O | Tiny pure compute |
| Must survive process restart | Must finish before response |
Running a worker
Check your CLI version:
atlantus --help
# often: atlantus job work --path .
Deploy HTTP (atlantus start) and the worker as two processes sharing the
same app directory and ATL_DATABASE_URL when the queue is durable.
App code
Enqueue from a handler or service using the job built-ins available in your
binary (atlantus check will accept valid names). Keep job handlers under
app/jobs/ as scaffolded.
Next: CLI.
CLI reference (atlantus)
Install the binary first: Install.
atlantus --version
atlantus --help
Everyday commands
| Command | Purpose |
|---|---|
atlantus new <name> | Scaffold a new app |
atlantus new <name> --with-auth | Scaffold with auth stubs |
atlantus check --path . | Structure + compile |
atlantus dev --path . | Development server |
atlantus dev --watch | Hot reload on .atl changes |
atlantus start --path . | Production-shaped serve |
atlantus build --path . | Compile / emit artifacts |
atlantus db migrate --path . | Apply SQL migrations |
Useful flags
atlantus dev --path . --host 127.0.0.1 --port 3000
atlantus start --path . --host 0.0.0.0 --port 8080
Project root
--path points at the directory with atlantus.toml (your app).
After atlantus new my-api && cd my-api, that is ..
Generators & extras
Depending on version, also available via atlantus --help:
gen— route/service stubsfmt— format.atlopenapi— OpenAPI from routesjob work— worker loop for durable jobs
Not required
You do not need cargo, rustc, or a checkout of the framework to use these
commands. Those appear only in contributor docs for people building Atlantus
itself.
Next: Deploy.
Deploy
Mental model
install atlantus binary → copy your app → migrate → start (+ optional worker)
No Rust toolchain on the server for app deploy.
1. Install the CLI on the server
Same as Install — download the release binary onto the VPS:
# example: linux x86_64 asset from GitHub Releases v0.2.1
sudo install -m 0755 ./atlantus-v0.2.1-linux-x86_64 /usr/local/bin/atlantus
atlantus --version
2. Copy your app
# from your machine — your project, not the framework source
rsync -a ./my-api/ user@server:/opt/my-api/
3. Environment
export ATL_ENV=production
export ATL_AUTH_SECRET='…' # if using auth
export ATL_DATABASE_URL='postgres://…'
export ATL_CORS_ORIGINS='https://app.example.com'
4. Migrate & start
cd /opt/my-api
atlantus db migrate --path .
atlantus start --path . --host 0.0.0.0 --port 3000
Optional worker:
atlantus job work --path . # if available in your version
Put Nginx/Caddy in front for TLS.
systemd sketch
[Unit]
Description=Atlantus app
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/my-api
Environment=ATL_ENV=production
Environment=ATL_AUTH_SECRET=change-me
Environment=ATL_DATABASE_URL=postgres://…
ExecStart=/usr/local/bin/atlantus start --path /opt/my-api --host 0.0.0.0 --port 3000
Restart=on-failure
[Install]
WantedBy=multi-user.target
Health
curl -fsS http://127.0.0.1:3000/health
curl -fsS http://127.0.0.1:3000/ready
Docker
If your team ships a container image that already contains atlantus, deploy
that image and mount/copy the app directory. You still do not need Rust on
the host — only the image build pipeline (CI) compiles the runtime.
Next: Examples.
Examples & next steps
Learn by building
- Install the binary
- Getting started
- Your first API
- Syntax + HTTP + Natives
- Views for HTML
- Deploy
Minimal recipes (copy into your app)
Health JSON
get "/health" {
def health(req) {
return json({ "status": "ok" })
}
}
Path param
get "/hello/{name}" {
def hello(req) {
return json({ "message": "Hello, " + req.param("name") + "!" })
}
}
HTML view
get "/hi/{name}" {
def hi(req) {
return view("hello/show", { "name": req.param("name") })
}
}
Sample apps
If your team ships sample trees (blog, queue worker), install them as normal app directories and run:
cd path/to/sample-app
export ATL_DATABASE_URL="sqlite:./tmp/app.db?mode=rwc"
atlantus db migrate --path .
atlantus dev --path . --port 3000
You never need cargo to run a sample app.
Editor
VS Code: install the Atlantus / .atl extension when your team distributes it
(VSIX or marketplace). The LSP talks to the same language surface as atlantus check.
Docs site
- Public: https://atl-docs.atlantus.network
- Local preview is for doc authors, not app developers
Keep learning
| Goal | Chapter |
|---|---|
| Types & modules | Language overview |
| DB | Database |
| Login | Auth |
| Background work | Jobs |
| CLI flags | CLI |