Shahathir (•◡•)

24 · Batu Caves, Selangor, Malaysia · 🇲🇾

professionally distracted

My Career Journey

  1. Financial Risk Group logo

    Financial Risk Group

    1yrs 3mos

    Assistant Software Developer

    Jun 2025 – Present

  2. Estee Lauder Companies logo

    Estee Lauder Companies

    6mos

    Software Engineer Intern

    Sep 2024 – Mar 2025

Tools & Platforms

TypeScript
JavaScript
Java
Python
PHP
Go
HTML5
CSS3
React
Next.js
Vite
Angular
Redux
React Router
Tailwind CSS
shadcn/ui
Material UI
Sass
Bootstrap
React Native
Node.js
TypeScript
JavaScript
Java
Python
PHP
Go
HTML5
CSS3
React
Next.js
Vite
Angular
Redux
React Router
Tailwind CSS
shadcn/ui
Material UI
Sass
Bootstrap
React Native
Node.js
Bun
Django
FastAPI
Spring Boot
Java Servlets
Express
PostgreSQL
MySQL
MS SQL Server
SQLite
Appwrite
Docker
AWS
Cloudflare
Nginx
Vercel
Netlify
DigitalOcean
Git
DBeaver
Postman
Bun
Django
FastAPI
Spring Boot
Java Servlets
Express
PostgreSQL
MySQL
MS SQL Server
SQLite
Appwrite
Docker
AWS
Cloudflare
Nginx
Vercel
Netlify
DigitalOcean
Git
DBeaver
Postman

Words I Live By

Shahathir is currently not listening to anything
Shahathir is currently not listening to anything

2026 © shahathir.me

Changelogs · Old site

  • AboutAbout
  • ThoughtsThoughts
  • TILTIL
  • BookmarksBookmarks
  • ExperienceExperience
  • ProjectsProjects
  • AccoladesAccolades
  • PhotographyPhotography
  • SongsSongs
  • StatsStats
  • UsesUses
  • ChatChat
  • Resume BuilderResume Builder
  • AboutAbout
  • ThoughtsThoughts
  • TILTIL
  • BookmarksBookmarks
  • ExperienceExperience
  • ProjectsProjects
  • AccoladesAccolades
  • PhotographyPhotography
  • SongsSongs
  • StatsStats
  • UsesUses
  • ChatChat
  • Resume BuilderResume Builder
January 10, 2026

Trading Monaco for CodeMirror, and learning what an editor library is

The Angular Monaco wrapper pinned us to a framework version and copied the whole editor into build assets. Moving to CodeMirror 6 changed how I think about editor libraries.

An app I work on embeds a code editor. It ran on Monaco — the editor that powers VS Code — through an Angular wrapper. Monaco is excellent, but the setup had problems: persistent runtime console errors, a build step that copied the entire monaco-editor package into the app's assets, and — the actual blocker — a wrapper that pinned us to a specific Angular major version, so I couldn't upgrade the framework underneath it.

I moved it to CodeMirror 6, and the interesting part wasn't the migration mechanics. It was realizing the two libraries have fundamentally different shapes.

Monaco is batteries-included: one big editor you switch features on and off. CodeMirror 6 is a small core you compose — you import only the extensions you actually want and push them into an array. Line numbers, indentation guides, a theme, a language — each is a separate package you opt into. Nothing you don't ask for is in the editor.

And because it's just a core plus extensions, it's small enough to drop straight into this page. Here's a real CodeMirror instance — editable, with the language and theme supplied as extensions (the theme tracks this site's light/dark). Switch languages and only the grammar you pick loads:

Loading editor…
@Component({
  selector: "app-code-editor",
  imports: [CodeEditor],
  template: `<code-editor
    [(ngModel)]="value"
    [language]="language()"
    [theme]="theme()"
    [extensions]="extensions()" />`,
})
export class CodeEditorComponent {
  value = model<string>("");
  language = input<string>("");
  isDark = input(false);
 
  // Compose exactly the features you want — nothing more ships.
  extensions = computed(() => [
    EditorView.theme({ ".cm-content": { fontFamily: "var(--font-mono)" } }),
    indentationMarkers(),
  ]);
  // A CodeMirror theme is just another extension, so drive it from the app's theme.
  theme = computed(() => (this.isDark() ? githubDark : githubLight));
}

Two things fell out of that shape:

  • The build got simpler by deletion. The single most satisfying diff was removing the glob that staged all of node_modules/monaco-editor into assets/. CodeMirror needs no asset staging at all — grammars load lazily through a LanguageDescription registry, so you don't bundle every language up front.
  • The real integration work was theming. Since a CodeMirror theme is just an extension, the job wasn't "configure the editor's dark mode" — it was bridging the app's own light/dark signal to a CodeMirror theme extension and recomposing when it flips. Once I stopped looking for a theme option and started treating it as an extension I supply, it clicked.

I went in expecting to swap one editor for another. I came out with a different definition of "editor library": not a product you configure, but a core plus the pieces you choose to assemble. The composability is the feature — you don't pay, in bytes or in lock-in, for the parts you never use.