{"title":"Migration Guide","description":"Upgrade an Amber 1.x application to the Amber 2.0 web-framework core","section":"","version":"v2","path":"migration-guide","canonical_url":"https://amberframework.org/docs/v2/migration-guide","markdown_url":"https://amberframework.org/docs/v2/migration-guide.md","inherited":false,"content_markdown":"# Migration Guide: Amber 1.x to 2.0\n\nStart with the smallest possible upgrade. For many Amber 1.x applications that\nalready use ECR and do not depend on Amber's old bundled integrations, the\nfirst—and sometimes only—application change is the Amber version in\n`shard.yml`. V2 is mostly additive framework work, not an invitation to rewrite\nyour product.\n\nThe standalone Amber CLI is independent from this runtime upgrade. Install or\nupdate it when you want V2 generators; an existing application can change its\nframework shard without being regenerated.\n\n> Amber `2.0.0-beta.5` release-gates the framework core and the new ECR web\n> template with Grant, Micrate, and SQLite. Existing applications do not have\n> to replace a working ORM to adopt the framework beta. Gemma, Asset Pipeline,\n> generated auth/API resources, and native output remain separate previews.\n\n## Try the direct upgrade first\n\n**File: `shard.yml` — change the existing `amber` dependency version.**\n\n```yaml\ndependencies:\n  amber:\n    github: amberframework/amber\n    version: 2.0.0-beta.5\n```\n\nKeep the rest of the application's dependencies unchanged for this first pass.\n\n**Run from: the application root, beside `shard.yml`.**\n\n```bash\nshards update amber\ncrystal spec\nshards build\n```\n\nIf those commands pass, launch the application through its normal development\ncommand and smoke-test the routes it actually serves. You do not need to adopt\nthe Schema API, replace an ORM, remove working front-end tooling, or regenerate\nthe project merely because V2 offers newer options.\n\n## When the direct upgrade needs a follow-up\n\nThe migration remains bounded, but it is not literally one line for every\napplication. Check the matching row only when the application uses that feature:\n\n| Existing application uses | Follow-up |\n|---|---|\n| ECR views and public static files | Usually no view-system migration |\n| Slang or another Kilt renderer | Convert those templates to ECR |\n| Amber's bundled Redis assumptions | Select and verify explicit session and pub/sub adapters |\n| Database drivers that arrived through Amber | Declare the application's driver directly |\n| Old `YAML.mapping` configuration types | Move those types to `YAML::Serializable` |\n| Framework-internal require paths | Replace them with the public Amber entry point or current API |\n| A working Webpack or other asset build | Keep it during the framework upgrade; migrate it separately if useful |\n\nThis inventory is why the guide contains more than a version edit. It is a map\nfor the exceptions, not evidence that an ordinary Amber application must be\nrebuilt.\n\n## What changes in V2\n\n| Application boundary | Amber 1.x starting point | Amber 2.0 path |\n|---|---|---|\n| Views | ECR, Slang, or Kilt | ECR for new and generated V2 views |\n| JavaScript and CSS | Commonly Webpack-managed | The released manifest fingerprints browser-ready CSS, JS, images, and fonts without a bundler |\n| Persistence | Commonly Granite or Jennifer | Existing apps may keep their working ORM; new CLI apps use Grant and a selected driver |\n| Sessions | Redis-oriented configuration | Built-in memory adapter or an explicitly registered external adapter |\n| WebSocket pub/sub | Redis-oriented configuration | Built-in in-process adapter or an explicitly registered external adapter |\n| Request validation | Controller-specific parsing | Optional typed Schema API |\n| File attachments | Application-specific integration | No bundled attachment library; Gemma is an ecosystem preview |\n\n## Before changing dependencies in a production application\n\nCreate a migration branch and capture a working baseline:\n\n1. Record the Crystal, Amber, ORM, database-driver, Redis, and asset-tool versions.\n2. Run the existing specs and build the application binary.\n3. Smoke-test the routes, session behavior, background work, WebSockets, and\n   static assets the application actually uses.\n4. Back up the database and prove the restore procedure before changing an ORM\n   or running a schema migration.\n5. List every Slang/Kilt template, Webpack entry point, Redis integration, and\n   framework-generated file that will need an explicit decision.\n\nDo not begin by deleting the old asset, persistence, or session configuration.\nKeep the last working path available until its replacement has passed the same\nchecks.\n\n## 1. Restore the framework baseline\n\nAfter the direct upgrade commands above, resolve any compile errors against the\n[V2 routing](../guides/routing/),\n[controllers](../guides/controllers/), [views](../guides/views/), and\n[configuration](../getting-started/) guides. Keep persistence and asset-tool\nchanges out of this step whenever possible.\n\n## 2. Move generated and legacy views to ECR\n\nAmber V2 removes Kilt and Slang from the supported framework path. Convert one\nview boundary at a time, preserve its rendered HTML contract, and run the\nrequest or feature specs that exercise it. New V2 generators emit ECR.\n\nThe [Views guide](../guides/views/) documents layouts, partials, helpers, and\nescaping behavior for the V2 path.\n\n## 3. Make sessions and pub/sub explicit\n\nAmber V2 includes in-memory session and pub/sub adapters. They keep a clean\napplication independent of Redis, but their state is local to one process.\n\nApplications that require shared state across processes or hosts must register\nand test an external implementation. Redis is not a built-in adapter guarantee;\nit is one backend an application can integrate through the adapter interfaces.\n\nUse the [Redis-to-adapters guide](redis-to-adapters/) to inventory the existing\nbehavior, then verify expiration, logout, session rotation, broadcasts, and\nmulti-process delivery before switching production traffic.\n\n## 4. Keep an existing persistence migration separate\n\nAmber CLI `2.0.6` installs Grant and SQLite in a newly generated web\napplication. That default does not require an existing Granite or Jennifer\napplication to change ORM during the framework upgrade. Keep its current\npersistence layer for the first pass, then verify compatibility against the\napplication's Crystal version, shard versions, and real queries.\n\nIf you choose to move to Grant, treat that as a second migration with its own\nbranch, database backup, restore proof, schema diff, representative reads and\nwrites, and rollback plan. Do not mix two ORMs unless ownership of connections,\ntransactions, migrations, and models is explicit. Review the\n[model-layer boundary](../guides/models/) and\n[Granite-to-Grant guide](granite-to-grant/) first.\n\n## 5. Preserve working assets before replacing tooling\n\nReleased CLI `2.0.6` compiles browser-ready files from `app/assets/` into a\nfingerprinted `public/assets/` manifest without requiring Node.js or a bundler.\nThat does not require an existing application to remove a working Webpack\npipeline during the framework upgrade.\n\nIf you adopt native ESM and the build-time Asset Pipeline contract, treat it as\nits own migration. Compare the complete manifest; rewritten local\nCSS and JavaScript dependencies; image, font, and binary bytes and MIME types;\nimport behavior; cache headers; read-only runtime; and atomic production\ndeployment before retiring the previous build. The\n[Webpack-to-ESM guide](webpack-to-esm/) and [Asset Pipeline guides](../guides/assets/)\ndescribe that independently reviewable migration; existing asset tooling may\nremain in place while the framework dependency changes.\n\n## 6. Adopt optional V2 features after the baseline passes\n\nSchema API, jobs, mailers, adapters, and expanded testing helpers can be adopted\nindependently. Add one application boundary, write or update its specs, and\nrestore the complete build before moving to the next.\n\n## 7. Migrate request validation action by action\n\nThe old `params.validation` API is deprecated, not removed. Existing blocks\ncontinue to compile and run after the V2 framework upgrade:\n\n**File: an existing action under `src/controllers/` — this code may remain\nunchanged during the first upgrade pass.**\n\n```crystal\nvalidation = params.validation do\n  required(:email) { |value| value.email? }\nend\n```\n\nAmber plans to retain that API throughout the initial V2 compatibility window\nand remove it no earlier than a later minor release such as 2.5. The exact\nremoval release will be announced separately. A deprecation warning is a prompt\nfor a gradual migration, not evidence that a V1 application must rewrite all\ncontrollers before adopting V2.\n\nFor one action at a time:\n\n1. create its request contract under `src/schemas/`;\n2. bind it above the action with `schema :action, SchemaClass`;\n3. read typed values with `validated_as(SchemaClass)` or the normalized hash\n   with `validated_params`;\n4. add `response_schema` when the action returns a machine-readable API\n   contract; and\n5. prove valid, malformed, unsupported-media, invalid-value, and invalid-response\n   behavior before converting the next action.\n\nThe declared schema runs automatically before the action. Do not replace the\nold validator with a manual `SchemaClass.validate(request)` call; that is not\nthe V2 controller API. The complete [Schema guide](../guides/schema-api/)\nshows the executable request and response path with exact file locations.\n\n## Verification gates\n\nUse observed behavior instead of an estimated migration timeline:\n\n| Gate | Evidence to keep |\n|---|---|\n| Framework | Dependency resolution, complete specs, and a compiled application binary |\n| HTTP | Representative request specs for routes, pipelines, parameters, redirects, and errors |\n| Sessions | Login/logout, expiration, rotation, cookie settings, and multi-process behavior where required |\n| WebSockets | Subscription, broadcast, reconnect, and cross-process delivery where required |\n| Assets | One build manifest; strict CSS, JavaScript, image, font, and binary lookups; rewritten dependency URLs; MIME/cache/compression responses; read-only runtime; and browser smoke tests |\n| Persistence | Database backup/restore proof, migrations, transactions, and representative reads and writes |\n| Deployment | A staging build produced through the same commands and configuration used in production |\n\nA migration boundary is complete when its previous behavior is reproduced or an\nintentional change is documented and tested—not when a predetermined number of\ndays has elapsed.\n\n## Getting help\n\nWhen reporting a migration problem, include the smallest failing example plus\nthe Crystal version, Amber version, previous Amber version, relevant shard\nversions, exact command, and complete output.\n\n- Review the [Amber V2 release notes](https://github.com/amberframework/amber/releases).\n- Ask in the [Amber Discord](https://discord.gg/vwvP5zakSn).\n- Report framework behavior in the [Amber issue tracker](https://github.com/amberframework/amber/issues).\n- Report CLI and generator behavior in the [Amber CLI issue tracker](https://github.com/amberframework/amber_cli/issues)."}