Installation
Meet Almasix
Section titled “Meet Almasix”Almasix is a Python web framework with expressive structure and first-class
async/await for ASGI (the async server interface apps run on). Create
applications with almasix new, then drive them with Smith — Almasix’s
in-app CLI:
pipx install almasixalmasix new blogcd blog# .venv comes next — see below — then:python smith migratepython smith serveTemplates, routing, validation, localization, and the ORM all live behind the
almasix.* package. You write application code; Almasix boots the container,
compiles your routes, and serves them over ASGI.
Requirements
Section titled “Requirements”- Python 3.11 or higher
- A way to install the global
almasixinstaller — pipx (recommended) or uv (uv tool install) - A project virtual environment for each app (or uv, which the scaffold prefers when it finds it)
- Node.js 18+ for the Vite stacks — the
nonestack needs no Node at all
Creating an Almasix project
Section titled “Creating an Almasix project”Install the framework once on your machine so almasix is on your PATH. That
global install only gives you the project generator — each application still
gets its own .venv with Almasix as a normal dependency. Modern Python
distributions block bare pip install … into the system environment (PEP 668);
use a tool installer instead.
-
Install the
almasixCLI globally (pick one):terminal pipx install almasix# or:uv tool install almasixDeveloping against a local checkout of the framework? Install that tree into an isolated tool environment the same way:
terminal pipx install --editable /path/to/almasix# or:uv tool install --editable /path/to/almasix -
Create a new application. Run it bare and it asks; pass flags and it asks only about what you left out:
terminal almasix new blogterminal Which frontend stack?● Tailwind CSS — Vite + Tailwind CSS 4 (recommended default)Bootstrap — Vite + Bootstrap 5 SassPlain CSS — Vite, no CSS frameworkNo frontend build — Server-rendered Prism only — no Node, no build stepWhich database will this application use?● SQLitePostgreSQLMySQLMariaDBScaffold a pytest suite (tests/)? smith test runs itInitialize a git repository?Install Python dependencies now? creates .venv, then pip/uv install -e .Run npm install and npm run build?Run the default migrations? creates users, sessions, cache, and the queue tables -
Create a virtual environment and install dependencies — unless you answered yes to creating a
.venvand installing (which did it for you):terminal cd blogpython -m venv .venvsource .venv/bin/activatepip install -e .With
--install(or answering Yes at the prompt),almasix newcreates.venv, runspip/uvinstall -e ., and installs the database extra when you picked PostgreSQL/MySQL/MariaDB. -
Run the migrations. Every new app is scaffolded with the default migrations (
users,password_reset_tokens,sessions, plus cache and queue tables). Unless you already answered yes to running them:terminal python smith migrate -
Build the frontend (any stack except
none):terminal npm installnpm run dev # dev server with hot reload, while you worknpm run build # hashed files in public/build, for a deploy -
Start the development server:
terminal python smith serveVisit the URL Smith prints (typically
http://127.0.0.1:3000).
Every question, and its flag
Section titled “Every question, and its flag”Every prompt has a command-line option and a documented default, so the same
almasix new is usable by a person and by a CI job. --no-interaction (or
-n) asks nothing and takes the defaults below.
| Question | Flag | Default without interaction |
|---|---|---|
| Frontend stack | --stack tailwind|bootstrap|plain|none |
tailwind |
| Database | --database sqlite|pgsql|mysql|mariadb|mongodb |
sqlite |
pytest suite under tests/ |
--tests / --no-tests |
scaffolded |
| git repository | --git / --no-git, --branch NAME |
not initialized |
| Python dependencies | --install / --no-install, --installer auto|uv|pip |
not installed (creates .venv + pip install -e . when yes) |
npm install && npm run build |
--npm / --no-npm |
run for Vite stacks when npm is on PATH |
| Default migrations | --migrate / --no-migrate |
not run (scaffolds users/sessions/cache/jobs; runs them when yes) |
| Where the app is created | --path DIR |
the working directory |
| Which stubs to scaffold from | --stubs DIR |
Almasix’s own |
# Scripted, start to finish: a Bootstrap app on PostgreSQL, in a git repo,# with dependencies installed and migrations run.almasix new shop -n --stack bootstrap --database pgsql --git --install --migrateTwo questions are skipped rather than asked when the answer could only be one
thing: npm when the stack has no package.json or npm is not installed, and
the migrations when the dependencies they need are not being installed.
Without a terminal — a pipeline, a Dockerfile, a subprocess — there is nobody
to answer, so almasix new behaves as though -n were passed and takes the
defaults in the table above. It never installs a package or touches a database
that nothing asked it to: a prompt’s displayed default is Yes for the person
at the keyboard who almost always wants it, and the documented default is No
for the script that did not say.
almasix stacks lists the stacks and databases without creating anything.
Frontend stacks
Section titled “Frontend stacks”| Stack | Ships | Error views |
|---|---|---|
tailwind |
Vite + Tailwind 4, rich landing/auth/layouts, branded errors | Tailwind-classed |
bootstrap |
Vite + Bootstrap 5 Sass, same UI kit | Bootstrap-classed |
plain |
Vite + hand-written CSS (Almasix brand tokens), same UI kit | default bundle, kit overrides |
none |
no Node; public/css/app.css; same UI kit |
default bundle, kit overrides |
Every stack scaffolds two layouts (layouts/minimal, layouts/app), a branded
landing page, login/register, a dashboard, and stack-styled error pages — centered
on the application name with Almasix orange accents.
The three Vite stacks ship vite-plugin-almasix.js, a dozen lines that write
public/hot while the dev server runs. Prism’s @vite directive reads that
file: while it exists the tags point at the dev server, and once it is gone they
point at the manifest npm run build wrote. See
Asset Bundling.
The stack also picks which error-view bundle is published into
resources/views/errors/, then the stack’s own richer error stubs overwrite
those files so a 404 matches the CSS the application loads. Change your mind
later with smith errors:publish --bundle.
Databases
Section titled “Databases”SQLite works out of the box, and the installer creates
database/database.sqlite for you. The other engines need their driver:
pip install almasix[pgsql] # PostgreSQLpip install almasix[mysql] # MySQLpip install almasix[mariadb] # MariaDBpip install almasix[mongodb] # MongoDB (Articulate documents)pip install almasix[sqlsrv] # SQL Serverpip install almasix[oracle] # Oracle (optional)pip install almasix[db] # all SQL engines above (not Mongo)--database writes the matching .env block. For the SQL engines it also
points config/database.py’s default at that connection. Choosing mongodb
configures MONGODB_* for Articulate document models and still keeps
SQLite as the SQL default so the scaffolded users/sessions/cache/jobs
migrations can run. Every other connection stays in the file, ready for an
environment variable to select it. See
Database: Getting Started and
Document stores.
The default migrations
Section titled “The default migrations”database/migrations/ in a new application is not empty. Three migrations
create the tables the framework itself reads:
| Migration | Tables | Read by |
|---|---|---|
0001_01_01_000000_create_users_table |
users, password_reset_tokens, sessions |
auth guards, the password broker, SESSION_DRIVER=database |
0001_01_01_000001_create_cache_table |
cache, cache_locks |
CACHE_STORE=database, and cache locks |
0001_01_01_000002_create_jobs_table |
jobs, failed_jobs |
QUEUE_CONNECTION=database, failed-job commands |
If you removed one and want it back — or you switched a driver and now need a table you did not before — each has a command:
smith cache:table # cache, cache_lockssmith queue:table # jobssmith queue:failed-table # failed_jobssmith session:table # sessionssmith notifications:table # notifications (the database notification channel)Those commands and the scaffold render the same stub, so a generated migration cannot disagree with what the driver expects.
Directory structure at a glance
Section titled “Directory structure at a glance”A fresh application looks like this:
blog/ app/ http/controllers/ models/user.py providers/ bootstrap/app.py config/ database/factories/user_factory.py database/migrations/ # three default migrations database/seeders/ resources/css/ resources/js/ resources/views/welcome.prism.html routes/web.py routes/api.py tests/ package.json vite.config.js vite-plugin-almasix.js smithRead more in Directory Structure and Asset Bundling.
Scaffolding from your own stubs
Section titled “Scaffolding from your own stubs”The scaffold is a stub tree, not strings inside the installer, so a team can publish it, edit it, and create every future application from its own copy:
smith stub:publish --scaffold # stubs/scaffold/{app,stacks}/…# edit stubs/scaffold/app/routes/web.py.stub, then:almasix new next-app --stubs stubs/scaffoldPlaceholders are the same ones the make:* generators use — {{ app_name }},
{{ app_display }}, {{ db_connection }}, {{ db_env }},
{{ frontend_section }} — and an unknown one is left as written, so a Prism
template’s own {{ slot }} survives being scaffolded.