Migrating Templates: What the Schematics Do and Don't In short: Angular's template migration tool is one of the best automatic tools in frontend work. It also makes exactly one decision it is not qualified to make — and that decision can leave bugs behind. The tool reads every template, rewrites the old directives, removes imports that are no longer needed, and tidies the result. On a large project it will correctly change thousands of templates in a couple of minutes. Knowing the one thing it gets wrong is the whole point of this lesson. Running it It asks for a folder (the whole project by default) and whether to tidy the formatting afterwards. It handles: with , , and → / with , , , , , → with the new variables and friends → / / wrappers that existed only to hold the directive → removed imports that are no longer needed → removed Commit before running it. Then look at the changes — not to check the rewrite is right (it reliably is), but to check the values. The one decision it cannot make The tool has to supply a value for every it creates. If the original had , it reuses that. If the original had no — which is most real code — it has nothing to work from, so it writes: This keeps the old behaviour exactly. without also tracked by position. So the tool is safe, which is the right choice for something automatic. But it also means the tool hands you a list of hidden bugs that were already there , now written down in plain sight. Any on a list that can reorder, filter, or lose an item from the middle will reuse page elements for the wrong items. The symptom is specific and worth recognising: a user deletes the second row of a table, and the third row's text box keeps the second row's typed value. The data is right. The page element was recycled with the wrong contents. It is a hard bug to trace back to a template if you do not know to look. Reviewing them Find every one the tool created: For each, ask one question: can this list ever reorder, filter, or lose an item from anywhere except the end? No — a fixed set of wizard steps, a static menu, a constant list. is right. Nothing to do. Yes — replace it with a stable id from your data. For items with no natural id, a combined key usually exists: If nothing unique exists at all, that is worth knowing on its own. It usually means your data is missing an id it should have. What it correctly leaves alone The tool skips things it cannot change safely, and leaves them working: Your own structural directives. is yours, not Angular's, and it keeps working. The syntax is not going away — only the three built-in directives are. An used in more than one place. If a template is both an branch and passed to a child component, the block form cannot express it. Deeply mixed structures where the rewrite would be unclear. After migrating, some templates will be a mix of and leftover . That is fine and it builds — the two work side by side. It just means you cannot remove from those components, and the tool knows this and leaves the import in place. What it does not attempt that is still needed. It is not going anywhere. It is still how you group elements without adding one to the page. The tool only removes ones whose only job was holding a directive. pipe → signals. Completely out of scope. That is a different tool and a lot of judgement. . No tool can decide what is worth delaying. That needs your knowledge of the product. Order of work If you are doing a large modernisation, templates come after structure: 1. Standalone ( ) — three runs, Chapter 1 2. Control flow ( ) — this lesson 3. review — by hand, and the part that matters 4. Signal inputs and queries — Chapter 4 Standalone first, because the control-flow tool removes imports, and those live in different places depending on whether a component is standalone. Doing it in this order means the tool only has one shape to handle. Turn up the checking first Templates are not checked as strictly as TypeScript by default. Turn it up before you start: With on, the better type checking in starts finding real bugs that was hiding — places where a value could be missing inside a branch you assumed was safe. That is a good thing to find during a planned migration rather than in production. But budget time for it : on a large project, turning on for the first time produces a lot of errors, and most of them are real. The architect's view Plan this as two pieces of work, not one. The tool run is fast and low-risk. The review is manual, needs judgement, and is where all the actual risk sits. Teams that treat the migration as "run the command, done" ship the second piece as latent bugs. Why the tool's default is correct — and still your problem. without also tracked by position, so the tool preserves behaviour exactly. That is the right call for something automatic: it cannot know your data, and guessing would be worse. But the output is a written-down list of a risk that was previously invisible. Treat as a review queue, not as finishe…