{
  "id": 5235066,
  "title": "Fine, I'll build my own text editor",
  "url": "https://urgent.news/2026/09/01/fine-ill-build-my-own-text-editor-5235066",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-01T17:12:15.000Z",
  "source": {
    "name": "Hacker News Best",
    "slug": "hacker-news-best",
    "url": "https://dbushell.com/2026/09/01/text-editor/"
  },
  "original_language": "en",
  "account": "Source material surfaced: <source da663541-c55>\n\nThe phrase \"They don’t make ’em like Sublime Text anymore\" echoed with many individuals. In recent times, software quality has declined. This realization led me to ponder my own coding skills. VS Code relies on Monaco Editor, a complex codebase. My transition to Apple silicon following years of using Intel-powered Macs improved performance. This gave me the opportunity to create a text editor from scratch. Initially, I rendered everything onto a canvas element. Although visually impressive, this approach imposes significant processing demands on the CPU. Interactivity is severely limited with a canvas. I compiled a list of essential features and brought them to life. The demo below showcases interactivity, allowing for typing and cursor movement. However, I dismiss suggestions regarding Vim bindings, as I have more pressing matters at hand. The canvas approach provides limited support for desired functionalities, one of which is critical. Customizing scrollbars is deemed unnecessary. To expedite development, I opted to utilize native browser overflow on a concealed element. A canvas-sized div is employed to synchronize with the text, and the scroll position determines render offsets on the canvas. While I'm content with the current progress, I remain concerned about the accessibility limitations of canvas. Rendering text on the canvas is not the solution; instead, I render it natively within the overflow div, making it editable using the contenteditable attribute. This attribute accepts plaintext-only values, perfect for code. To avoid latency spikes, spellcheck must be disabled. How long did it take me to discover this solution? Days! Contenteditable enhances native text selection and undo functionality, among other accessibility enhancements. The Selection API provides metrics for rendering a custom text cursor, while ::selection enables styling. The caret-color is set to invisible for aesthetic purposes, albeit unconventional. Contenteditable proves promising, but performance issues arise with larger text. Chromium browsers exhibit poorer performance compared to WebKit and Firefox, though the inconsistency remains uncertain. I question whether a plaintext contenteditable or a simple textarea would be more performant. The answer is clear: a textarea outperforms in terms of longer text handling. In the final demo, I incorporated syntax highlighting. Initially, I intended to employ custom ::highlight on the contenteditable element. Since contenteditable lacks CSS highlights, an additional layer was necessary. Div soup was utilized for displaying visible lines, integrating MicroLighter. Edit: The OpaqueRange API and EditContext API present potential enhancements for textarea. CSS highlights introduce performance bottlenecks, and the use of Tree-sitter for syntax tree generation is suggested as a more robust solution. Although I initially aimed to avoid virtualized scrolling, it can be improved using the inverse sticky technique. Alternatively, reverting to contenteditable may prove advantageous for handling file sizes that exceed performance limitations. I am now 90% of the way to creating a functional text editor with minimal features. Further refinements, such as tab indentation, can be easily implemented. My demos, though unoptimized and lacking perfect accessibility, demonstrate that starting from a challenging position is not insurmountable. Rendering on canvas would present significant hurdles. I file this project away for future endeavors. JavaScript strings and text ranges operate with UTF-16 code units, making it easy to inadvertently introduce bugs. I acknowledge potential errors in my demonstrations and leave with a code example to challenge fellow developers.",
  "summary": "Article URL: https://dbushell.com/2026/09/01/text-editor/ Comments URL: https://news.ycombinator.com/item?id=49524863 Points: 236 # Comments: 233",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 2,
    "also_reported_by": [
      {
        "outlet": "Lobsters",
        "title": "Fine, I’ll build my own text editor",
        "url": "https://urgent.news/2026/09/01/fine-ill-build-my-own-text-editor",
        "published": "2026-09-01T11:18:22.000Z"
      }
    ]
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}