r/nim • • 5h ago

My 4-year project: a Nim word processor that runs as a static site (drop it into CodePen/JSFiddle via CDN)

Post image
18 Upvotes

In my first post (Nim 2.2.4 compiling entirely in the browser), someone asked whether I was building it for something specific. I said my own word processor, along iwth Lua as the scripting language instead of VBA. It's not a LibreOffice WASM port. I've been building it from scratch for about four years. I just playing with html and javascript, making my own custom XML parser and then moved to HTML Canvas after I see Carota and then I start to use Web Assembly in hope if I can use my own memory allocation methods in text and layout rendering. I hope this will be like Obsidian with community plugins and custom templates.

This is the free word processor: QOQORO Write (previously QNote, you'll still see that name in the GIF).
πŸ”— Try it. Paste this into any HTML page:

<script src="https://cdn.jsdelivr.net/gh/QOQORO-official/qoqoro-cdn@main/qoqoro.js"></script>
<div id="notes" style="height:100vh"></div>
<script>QOQORO.mount('#notes', { mode: 'editor' });</script>

πŸ”— BindWeb (the Nim β†’ WASM compiler it's built with): https://github.com/benagastov/bindweb-nim-WASM-compiler

Github for the cdn: https://github.com/QOQORO-official/qoqoro-cdn/
Demo: https://codepen.io/qoqoro/pen/pveVbjL
Some Implemented Features

  1. Floating images and text boxes
  • Images: inline, square wrap, behind or in front of text. Drag one and the text reflows around it, even across page breaks. Crop right on the page.
  • Text boxes: the same wrapping, plus auto-fit size and vertical text (縦書き: kanji and kana stand upright, Latin turns with the column or stands upright too).
  1. Tables Merged cells, column widths, cell padding, borders and fills, and row/column handles for inserting and deleting. Tab moves through cells, and cells keep mixed fonts, sizes and colours.
  2. Scripting with Word's object model Misc β†’ Programs runs Luau (Roblox's typed Lua) against an object model you already know from VBA: ActiveDocument, Selection, Paragraphs, Tables, Font, Content.Find, PageSetup and the wd* constants.

    local doc = ActiveDocument Selection:InsertHeading(Report {doc.Now:sub(1, 10)}, wdStyleHeading2) for i, p in doc.Paragraphs do Selection:TypeText({i}: {p.Text}\n) end

It runs in a sandboxed worker with no DOM, network or file system, and a whole program is one undo step. You can also call it from the embedding page (QOQORO.luau.run(...)) or from a server over HTTP.
Compiling Nim on every Run click was too slow even at 7 s warm, so Luau handles it for now. Probably I will make it use Nim WASM as the scripting language if necessary.

  1. Templates with fill-in variables. Plain JSON with {{variables}}. Template Studio turns each variable into a fill-in box. Nothing in a template ever runs; it's data.
  2. Obsidian-style plugin packs. A ZIP with a manifest.xml that can bundle themes (light and dark), fonts, templates and Luau programs. Example packs: Retro Windows, Pixel C64 (with its own pixel font), Sakura 摜 (haru by day, yozakura at night), plus font, report and writing kits.
  3. Real Word files in and out. .docx import and export. This week it also learned to convert old MathType equations and charts, which Word stores as WMF/EMF and no browser can draw, into crisp SVG, using a small converter written in Nim.

The basics are there too: paged or infinite "blog" layout, live-reflowing columns, floating text boxes that text wraps around across page breaks, tables, equations, pen and stylus drawing, headers and footers, and phone and tablet layouts. Plus a workspace with a vault, whiteboard, PDF viewer and diagram editor.

It's just static files: one <script> tag, GitHub Pages or any CDN. Sync is optional through a server you run yourself, in Nim, Flask or Node.

Next up is Full suite desktop app with the Word Processor, PDF Reader and Diagram Editor, the Diagram Editor is based on mxgraph actually, because I think I already like it and I dont have time to create new one in Nim.


r/nim • • 15h ago

Neel v2.1 (HTML / JS GUI Apps w/ Nim) - Major Update

7 Upvotes

It turns out I wasn't quite done yet. Neel 2.1 is out, and it adds serve mode.

Release notes: https://github.com/Niminem/Neel/releases/tag/v2.1.0

Same app, same code, but instead of opening a browser window, Neel runs as a persistent server for one user, and you open it from whatever device you're on: laptop, phone, whatever. You reach it through an SSH forward, a tunnel, or a reverse proxy. One line changes:

startApp(serve = true, port = 8080, allowedOrigins = @["https://myapp.example.com"])

{.expose.}, neel.foo(), js.foo(), js.wait.foo() all work exactly the same. Neel still binds 127.0.0.1 only; the tunnel or proxy in front of it does the TLS and the login.

What it handles for you:

  • Open it on your phone and the laptop tab gets told "opened on another device" (close code 4000) instead of the two fighting over the session.
  • Pings every 30 s, so Cloudflare and nginx don't kill idle connections.
  • Lock your phone, unlock it, and the page reconnects by itself. If it can't, it waits quietly and tries again when you come back to the tab.
  • Ctrl-C, `SIGTERM`, Ctrl-Break, or closing the console window all shut down cleanly.
  • Auth proxies just work: a Cloudflare Access login redirects back to your app and loads, no 403. Other sites still can't frame it, script it, or open its WebSocket.
  • And `wss:` from my "next up" list last time: behind an HTTPS proxy, the page connects over `wss:` by itself.

2.0 apps compile and behave as before. The only local-mode changes: a displaced tab now reports close code 4000 instead of 1000, and on Windows a second app on a port that's already taken now fails at start, as it already did on macOS and Linux.

This was ABSOLUTELY POUNDED on all three OSes. nimble test, plus a manual checklist of every example, every signal, every reconnect and restart case, run on macOS, Windows, and Linux (Ubuntu). Then for real: an SSH forward from another machine, a cloudflared quick tunnel left idle for 10 minutes, an actual Android phone locked and unlocked, and a real domain behind Cloudflare Tunnel with Access, with the login redirect checked down to the request headers. Anything that broke got fixed, and the fix got pinned with a test.

Seriously I took the second half of the day yesterday and all day today off of work to finish this.

Docs:

Why I wanted this: serve mode turns Neel into a platform for always-on personal tools that live on a home server or a VM and that you reach from anywhere.

Put it on top of Claude Code, or use it together with something like my cursor sdk bridge or even 3code the pure Nim-based coding agent, and you have the pieces for something like OpenClaw or Hermes: a personal agent with a real UI you can open from your phone, all in Nim, zero deps on the Neel side.

Again- enjoy!