A few weeks ago, I opened my personal website and felt that familiar pang of developer guilt.
My site was frozen in time—running on Angular 12 and showcasing work from years ago (ASP.NET MVC, C#, AngularJS, and transitions through early enterprise versions). While that foundation taught me how enterprise software scales, looking under the hood felt completely disconnected from what I actually do every day.
At my day job, I work in production Angular 19, building high-density freight audit ledgers, embedded Stripe and Plaid checkout rails, and custom monorepo workspaces. Yet, my personal site was still carrying the weight of a decade-old legacy footprint.
I didn't throw away my domain or start over from scratch elsewhere—I sat down and did a complete rewrite from the ground up, jumping ten major versions directly from Angular 12 to Angular 22.
Here is what went into the rewrite, the leap across ten versions, and what I learned along the way.
1. The 10-Version Leap: Angular 12 to Angular 22
Jumping from Angular 12 straight to Angular 22 feels like stepping into an entirely different framework—in the best way possible.
In Angular 12, simple features still required an incredible amount of boilerplate ceremony:
- Bloated
NgModuledeclarations tying components together - Heavy zone-based change detection running dirty checks everywhere
- Repetitive RxJS subscriptions for basic synchronous component state
- Verbose structural directives (
*ngIf,*ngFor) littering templates
Rewriting the codebase directly in Angular 22 stripped that cruft down to essentials:
- Zero NgModules: Completely standalone architecture where components only import what they use.
-
Built-in Control Flow: Replacing structural directives with modern
@ifand@forsyntax made templates dramatically more readable and cut bundle overhead. - Signals-First Reactivity: Moving local UI state to fine-grained Signals eliminated manual subscription cleanup and unnecessary async pipe chains.
Instead of fighting legacy upgrade paths incrementally, rewriting the codebase cleanly unlocked modern build speeds, microscopic bundle sizes, and a developer experience that actually feels fun.
2. Replacing the "Resume Checklist" with Real Problems
When you have been writing code for a while, the default trap is listing every library, runtime, and tool you have ever touched. But a giant list of 30 logos doesn't tell anyone what you actually solve.
Instead of keeping that passive list, I structured the rewrite around real production challenges:
- Handling Financial Flows Securely: Integrating Stripe Elements and Plaid Link for ACH and credit card processing. In financial checkout, it's not just about rendering an input; you have to manage strict tokenization boundaries, handle asynchronous webhooks, and build optimistic state updates with graceful failure recovery.
-
Fixing State Leaks: Moving away from broad global state caches that can accidentally preserve sensitive checkout tokens across routes. Migrating to route-scoped
@ngrx/component-storeinstances tied checkout streams directly to the component lifecycle, cutting memory overhead by 42% and eliminating stale session state. -
Daytime Continuous Delivery with Kubernetes: For a long time, enterprise deployments meant stressful, off-hours maintenance windows to prevent broken sessions. This year, our team migrated the frontend onto Kubernetes clusters. Today, our delivery pipeline runs like clockwork:
- Azure DevOps drives our sprint planning and backlog execution.
- GitHub manages our repositories, pull request reviews, and deployment triggers.
- Kubernetes handles rolling zero-downtime updates with automated health probes.
- Split.io & Harness decouple code deploys from feature releases via canary toggles.
- Grafana gives our team real-time visibility into pipeline build times, ingress health, and client error rates.
We went from dreading after-hours release windows to shipping zero-downtime updates in the middle of a Tuesday afternoon without interrupting active user checkout sessions.
Every project card on the new site includes a deep-dive drawer that breaks down the original business problem, technical deliverables, concrete metrics, and architectural takeaways.
3. Building a 12-Card Skills Grid (and the SVG Math That Broke My Layout)
Instead of a generic chip list, I built an interactive 12-card skills grid organized into clean, complementary pairs:
- Core Architecture: Angular 19 & TypeScript
- State Architecture: Angular Signals & NgRx ComponentStore
- Reactive & Workspace: RxJS Streams & Angular Monorepo
- Design Systems: Figma Tokens & Tailwind / SCSS
- Enterprise Platform: Stripe & Plaid + .NET / C#
This seemed straightforward until I started building the custom inline SVGs for each card.
A few visual bugs quickly showed up:
-
Aspect Ratio Issues: One icon used a vertical
256x384coordinate space inside a square container, which compressed it into a tiny letterbox. Normalizing everything to a consistent256x256bounding box brought back consistent sizing. - Clipping on High-DPI Screens: A Tailwind path had coordinates extending past the viewBox boundary, silently cutting off roughly a third of the wave graphic.
- Compound Brand Layouts: Putting Stripe and Plaid into a single card required manual coordinate offsets and scaling so neither logo crowded the other.
Getting all 12 cards aligned symmetrically across mobile, tablet, and desktop took plenty of trial and error, but the end result is fast, responsive, and readable.
4. The Enterprise Reality vs. The Personal Lab
One question I had to answer was: Which Angular version should I highlight?
In enterprise engineering, you don't rewrite critical production apps the moment a new framework version is released. At work, our core applications run stably on Angular 19. It is reliable, deterministic, and supports high-volume financial workflows where stability is non-negotiable.
For my personal site rewrite, though, I had no legacy constraints. Rewriting it in Angular 22 let me work directly with the latest signal primitives and zero-debt setups.
Highlighting both is honest: it demonstrates knowing how to keep enterprise production software stable while continuously experimenting with modern tools.
5. Key Takeaways from the Rewrite
- Don't fear the version jump: Moving across ten framework versions sounds daunting, but starting with a clean rewrite instead of chaining 10 migration CLI passes let me adopt modern idiomatic patterns immediately.
- Delivery maturity is frontend engineering: A frontend engineer isn't just writing components. Understanding how your bundle is packaged into Docker, deployed on Kubernetes, toggled via Split.io, and monitored in Grafana makes you dramatically more effective at work.
- Be specific about domain work: Anyone can say they "integrate APIs." Explaining how you tokenized corporate bank accounts through Plaid Link or automated freight invoice audit rules proves actual hands-on business impact.
- Treat your own site like a real project: Responsive breakpoints, clean accessibility, component lifecycle cleanups, and lean build budgets belong on your personal domain just as much as an enterprise app.
You can check out the live site here: tanyamott.com
When was the last time you overhauled your personal site? Have you made a multi-version framework leap recently? Let's chat in the comments!
Top comments (0)