Amber V2 Web Template
Amber CLI 2.0.6 generates a complete server-rendered web application with
ECR, Grant ORM, Micrate migrations, and SQLite. The first database-backed
feature needs no database server, Node.js process, or front-end package manager.
The same template includes the released build-time asset manifest, so its
homepage exercises the frontend contract documented for production apps.
Run from: the parent directory where my_app/ should be created.
amber new my_app --type web
cd my_app
Web, ECR, and SQLite are the defaults, so amber new my_app is equivalent. Use
-d pg or -d mysql when the application should start with a server database.
Where the examples go
Commands on this page run from the generated application root unless a closer
label says otherwise. Every code or tree example names its source file,
generated output, or reference role. Replace my_app with the actual generated
target name when a command includes it.
Generated project
Generated output: the top-level structure under my_app/.
my_app/
├── .amber.yml
├── .gitignore
├── README.md
├── shard.yml
├── config/
│ ├── application.cr
│ ├── assets.cr
│ ├── database.cr
│ ├── routes.cr
│ └── environments/
│ ├── development.yml
│ ├── production.yml
│ └── test.yml
├── db/
│ ├── migrations/
│ └── seeds.cr
├── app/assets/ # authored; source control
│ ├── stylesheets/app.css
│ ├── javascript/app.js
│ ├── images/amber-crystal.svg
│ ├── images/favicon.svg
│ ├── fonts/.gitkeep
│ └── files/.gitkeep
├── public/
│ ├── assets/ # generated; gitignored
│ │ ├── manifest.json
│ │ └── ...fingerprinted files...
│ └── robots.txt
├── spec/
│ ├── spec_helper.cr
│ ├── controllers/home_controller_spec.cr
│ └── channels, jobs, mailers, models, requests, schemas/
└── src/
├── my_app.cr
├── controllers/
│ ├── application_controller.cr
│ └── home_controller.cr
├── views/
│ ├── home/index.ecr
│ └── layouts/application.ecr
└── channels, jobs, mailers, models, schemas, sockets/
The empty extension directories give generators stable destinations. The
generated README.md names those destinations again while a developer is
working inside the project.
Exact dependency contract
File: shard.yml — generated dependency manifest.
crystal: ">= 1.20.0, < 2.0"
dependencies:
amber:
github: amberframework/amber
version: 2.0.0-beta.5
grant:
github: crimson-knight/grant
commit: 2665a978b43ac608c68cde9243821f8f8f053372
asset_pipeline:
github: amberframework/asset_pipeline
version: 0.37.0
sqlite3:
github: crystal-lang/crystal-sqlite3
version: ~> 0.23.0
The exact Grant commit is intentional while its V2 release is finalized. Amber and Grant changes are not pulled from moving branches during application generation.
The CLI embeds its web scaffold in the executable. amber new does not fetch a
template manifest, so updating the CLI changes future projects but never
silently rewrites an existing application.
Database connection
File: config/database.cr — generated SQLite registration.
require "amber"
require "grant"
require "grant/adapter/sqlite"
Grant::Connections << Grant::Adapter::Sqlite.new(
name: "primary",
url: ENV["DATABASE_URL"]? || Amber.settings.database_url
)
Every generated Grant model declares connection primary. DATABASE_URL
overrides the environment YAML, which makes production configuration explicit
without putting credentials in source control.
File: config/environments/development.yml — generated development values.
name: my_app
server:
host: 127.0.0.1
port: 3000
secret_key_base: "generated-development-secret"
database:
url: "sqlite3:./db/my_app_development.db"
session:
key: "my_app.session"
store: "signed_cookie"
adapter: "memory"
expires: 0
logging:
severity: "debug"
colorize: true
config/environments/test.yml uses db/my_app_test.db. Production leaves the
URL empty so deployment must provide DATABASE_URL.
Generate the first persisted resource
Run from: the application root beside shard.yml.
amber generate scaffold Pet name:string:required species:string:required adopted:bool
amber database migrate
AMBER_ENV=test amber database migrate
crystal spec
The scaffold command writes:
| Concern | Exact destination |
|---|---|
| Grant model | src/models/pet.cr |
| Request schema | src/schemas/pet_schema.cr |
| HTML CRUD controller | src/controllers/pet_controller.cr |
| Index, show, new, edit, and shared form ECR | src/views/pet/ |
| Reversible Micrate SQL | db/migrations/*_create_pets.sql |
| Model and request specs | spec/models/pet_spec.cr, spec/controllers/pet_controller_spec.cr |
| Resource routes | config/routes.cr |
The generated migration contains -- +micrate Up and -- +micrate Down
sections. amber database migrate applies the development database; setting
AMBER_ENV=test applies the separate test database.
Amber CLI 2.0.6 generates an HTML schema that declares
application/x-www-form-urlencoded. PetController binds it with
schema :create, PetSchema and schema :update, PetSchema, then reads the
request-local typed values through validated_as(PetSchema). Invalid input is
stopped before the action and re-renders the ECR form with field errors. The
controller does not manually construct and validate a second schema object.
This is the released CLI 2.0.6 and framework 2.0.0-beta.5 path.
Run from: the application root — useful database maintenance commands.
amber database status
amber database rollback
amber database redo
amber database seed
Released frontend and asset contract
The starter uses warm paper colors, faceted geometry, editorial type hierarchy, and compact status labels. It is authored entirely in the generated ECR and local CSS.
File: src/views/layouts/application.ecr — generated front-end entry point.
<%= favicon_tag("images/favicon.svg") %>
<%= stylesheet_link_tag("stylesheets/app.css") %>
<%= javascript_importmap_tag(
{"app" => "javascript/app.js"},
preload: ["javascript/app.js"]
) %>
<script type="module">import "app";</script>
The visible page is src/views/home/index.ecr, the component layer is
app/assets/stylesheets/app.css, and browser behavior begins in
app/assets/javascript/app.js. See Import maps for
adding local ESM modules without a Node.js runtime or bundler.
amber new compiles the first manifest before it returns. The generated
boundary is:
Generated files and authored source — ownership reference:
my_app/
├── app/assets/ # authored; source control
│ ├── stylesheets/app.css
│ ├── javascript/app.js
│ ├── images/amber-crystal.svg
│ ├── images/favicon.svg
│ ├── fonts/.keep
│ └── files/.keep
├── config/assets.cr # runtime manifest resolver
├── public/
│ ├── assets/ # generated; gitignored
│ │ ├── manifest.json
│ │ └── ...fingerprinted files...
│ └── robots.txt # authored
└── src/views/layouts/application.ecr
Run from: the generated application root.
amber assets build
amber assets check
amber watch rebuilds the manifest before application compilation and watches
app/assets/**/* alongside Crystal and ECR source. Older applications can use
the explicit scripts/build_assets.cr wrapper from the Asset Pipeline
guide while adopting the same contract.
File: config/assets.cr — generated runtime resolver configuration.
Amber::Assets.configure(
manifest_path: "public/assets/manifest.json"
)
File: src/views/layouts/application.ecr — generated helper usage.
<%= favicon_tag("images/favicon.svg") %>
<%= stylesheet_link_tag("stylesheets/app.css") %>
<%= javascript_importmap_tag(
{"app" => "javascript/app.js"},
preload: ["javascript/app.js"]
) %>
<script type="module">import "app";</script>
File: src/views/home/index.ecr — generated brand image usage.
<%= image_tag("images/amber-crystal.svg", class: "starter-crystal", alt: "") %>
The generated stylesheet references
../images/amber-crystal.svg, proving that CSS URLs are rewritten as well as
ECR helpers. Images, fonts, favicons, and arbitrary binaries receive the same
content-addressed manifest treatment as CSS and JavaScript. User uploads do not;
they remain persistent runtime data outside the authored tree.
Routes and request pipelines
File: config/routes.cr — generated pipeline and route ownership.
webincludes errors, logging, sessions, flash, and CSRF.staticserves files underpublic/.apiis available for explicitly registered API routes./initially rendersHomeController#index.resources "/pets", PetControlleris added by the Pet scaffold.
Controller generation alone does not edit routes. Scaffold generation does, because its controller and views implement the complete resource contract.
Compile and browser contract
Run from: the generated application root.
shards install
amber assets check
crystal spec
crystal build src/my_app.cr -o bin/my_app
amber watch
Open http://127.0.0.1:3000/ and
http://127.0.0.1:3000/pets/new. The release test also submits that generated
form, reads the stored Pet, edits it through _method=PATCH, and verifies the
updated record.
The release gate runs amber assets build and amber assets check, starts the
compiled application with its release directory read-only, and requests the
fingerprinted CSS, JavaScript, image, and font URLs rendered from
public/assets/manifest.json. It also verifies SRI, MIME types, immutable cache
headers, gzip negotiation, and persisted Pet create/update behavior.
The supported web-template gate covers macOS, x86-64 Linux, and ARM64 Linux. Windows x86-64 must compile the same generated database-backed application in CI, but it does not yet have a CLI release archive. See Beta support for the platform boundary and Build a Pet Tracker for the complete first application.