Neil Belani Software Developer
open to opportunities

NB.OS — everything lives inside

Countries visited

0 and counting — tap to explore

NEIL
BELANI

I keep systems running, build PCs from scratch, and make the web do fun things.

SysAdmin @ OWL360IT · GTA · 50+ custom builds

11 projects

My time · Your time

MeToronto, CA
Youlocal

Theme

nb@os:~$ theme --list

Contact

Selected work

Projects I'm working on.

Systems built and shipped end to end — automation pipelines, e-commerce, self-hosted infrastructure and real-time graphics. Each entry covers the problem, the approach, the technical decision that mattered, and the outcome.

AI & AutomationLive

DealerList AI

Dealership inventory published to Facebook Marketplace in bulk — listings generated, forms populated, sold units withdrawn automatically.

  • AI listings
  • Marketplace autofill
  • Inventory sync
  • SaaS

Read the case study

Problem

Facebook Marketplace is where local used-car buyers are, and it offers no bulk path for vehicle listings. Every car is a manual form: photos, mileage, trim, a description someone has to write. Across a 200-car lot that is a full-time role, so most dealerships list their twenty best vehicles and leave the rest invisible.

Approach

A platform connecting dealership inventory to Marketplace: listing copy generated per vehicle, Marketplace forms populated rather than typed, sold units withdrawn automatically, and per-salesperson attribution across the lot. Dealers work a review queue instead of a form.

Technical decision

The model writes; it never asserts. Generated copy is constrained to facts the system can verify, and anything unverifiable escalates to a human rather than becoming a confident guess. A fluent listing with one wrong specification costs a sale and the dealership's credibility — so throughput is deliberately capped in favour of accuracy.

Outcome

Live at dealerlist.ai. Product, pipeline and interface built and operated end to end.

Stack

  • AI listing generation
  • Facebook Marketplace
  • Browser extension
  • Inventory sync
  • SaaS

Content SystemsLive

othertenants

A short-form channel that scripts, renders and publishes itself on a schedule — with one human approval in the loop.

  • Remotion
  • GitHub Actions
  • Discord
  • Free tier only

Read the case study

Problem

Short-form only works with consistent output, and consistency is what ends solo channels. Every video is the same five jobs — select a subject, script it, render it, publish it, repeat tomorrow — and a stall in any one of them halts the whole pipeline.

Approach

A queue-driven pipeline. Subjects are scripted, rendered to vertical video with Remotion, and published to Instagram and YouTube Shorts by a scheduled GitHub Actions workflow. One manual gate remains: each finished render is posted to Discord, and nothing ships without an approval reaction.

Technical decision

A deliberate human gate inside an otherwise autonomous pipeline. Full automation was achievable, but the failure mode — publishing incorrect content to a live audience — is not reversible. Siting the gate in Discord keeps approval to a two-second action on a phone, which is the only reason it survives contact with a real schedule.

Outcome

Publishing on schedule with no server and no compute bill — scheduling and rendering both run inside free tiers.

Stack

  • Remotion
  • GitHub Actions
  • Discord approval gate
  • YouTube Shorts
  • Instagram
  • Free tier only

AI & AutomationLive

Cerulean Finds

Auction lots in, a live storefront and a Marketplace-ready feed out. Nothing is entered twice.

  • HiBid
  • Storefront
  • Facebook import

Read the case study

Problem

Reselling from HiBid auctions means repeating the same data entry after every win: transcribing lot details, building a product page, then retyping all of it again to list on Facebook. In a resale business, that time is the margin.

Approach

A pipeline running from HiBid through the storefront and back out to Facebook. Won lots are ingested with their details and photographs, published as products, and exported in the shape Facebook's importer expects — so a lot is entered zero times.

Technical decision

Normalisation happens once, in the middle, rather than inside each integration. Auction data arrives inconsistently — titles vary, condition is buried in prose, photographs come in arbitrary order. Cleaning to a single internal product model means both outputs read that model instead of the source, so an additional sales channel costs one exporter rather than another parser.

Outcome

Live at ceruleanfinds.com, running the listing side of the business.

Stack

  • HiBid ingest
  • Normalised product model
  • Storefront
  • Facebook import feed

AI & AutomationLive

Second Brain

Deterministic memory for AI assistants — plain markdown, a flat index, and the same answer to the same question every time.

  • Node CLI
  • Markdown
  • No vector DB
  • Obsidian

Read the case study

Problem

Assistant memory is usually built by embedding everything into a vector database and trusting the nearest neighbour. For factual recall over a known corpus that is the wrong trade: the requirement is the correct note, not the closest one. Semantic retrieval is also unauditable — a wrong result carries no explanation and cannot be grepped.

Approach

A local vault of atomic markdown notes with a flat index — one line per note — and a Node CLI over the top.

Writes are atomic: the note, its index line and the commit land together, so the index cannot drift from what is on disk. Recall scores a query against that index and returns the matching note together with the heading and line numbers it came from, so every answer arrives with a citation that can be checked. Roughly fifty notes, each small enough that an incorrect one fails in isolation instead of contaminating its neighbours.

Technical decision

No embeddings, by design. Determinism, auditability and greppability were worth more than fuzzy matching: the same query returns the same note, the index is readable in a text editor, and a wrong answer is a fixable bug rather than a similarity score. Storing plain markdown also means the corpus outlives any single assistant.

Outcome

In daily use as the memory layer across multiple AI assistants. Git tracks history locally; there is no remote and nothing synchronises off the machine.

Stack

  • Node CLI
  • Atomic markdown notes
  • Flat text index
  • Obsidian-compatible
  • Local only

Web AppsLive

Sip & Sit TO

A Toronto cafe review site maintained day to day by a non-technical operator, at zero running cost.

  • Self-serve editing
  • Photo galleries
  • Free tier only

Read the case study

Problem

A content site is only sustainable if the person running it can update it without a developer. Otherwise every new cafe, photograph or menu change becomes an engineering request and the site quietly stops being updated. The budget for a hosted CMS was zero.

Approach

A review site built around photo galleries and menus, with browser-based editing for the operator: add a cafe, add photographs to it, correct a menu. Hosting, image storage and the editing layer all run inside free tiers.

Technical decision

The editing surface was scoped to the two tasks the operator actually performs, rather than exposing a general admin panel. A generic CMS is a second product to learn; here the fields are ordered to match how the information arrives — on site, phone in hand.

Outcome

Live and maintained entirely by its operator, with no developer in the loop.

Stack

  • Static site
  • Self-serve editing
  • Photo galleries
  • Free tier hosting & storage

Web AppsLive

Cerulean Scents

A perfume storefront across hundreds of SKUs where every product image is verified before a customer can reach it.

  • Image manifest
  • Hundreds of SKUs
  • Storefront

Read the case study

Problem

A perfume catalogue is mostly photography, and vendor image sets are unreliable in several directions at once: filenames that do not match SKUs, one bottle with three shots and the next with none, the same scent spelled two ways. A catalogue that trusts the folder ships broken tiles to customers.

Approach

A storefront covering hundreds of SKUs, rendered from a verified image manifest — a checked mapping from SKU to the images that genuinely exist, generated rather than hand-maintained. Because rendering reads the manifest, a missing photograph is a known gap with a deliberate fallback instead of a broken image in front of a buyer.

Technical decision

The manifest is a build-time artifact, not a runtime lookup. Asking whether an image exists during rendering costs a request per SKU and fails in front of the customer; answering it up front turns a 404 someone else discovers into a diff reviewed before release — and keeps the storefront deployable as static output.

Outcome

Live, with the catalogue, verified imagery and commerce mechanics in place.

Stack

  • Verified image manifest
  • Static storefront
  • Build-time verification

InfrastructureLive

Immich Photo Server

A self-hosted photo library replacing Google Photos — a decade of images on owned hardware, with the features that justified the subscription.

  • Immich
  • Docker
  • Self-hosted
  • Linux

Read the case study

Problem

A growing photo library on a hosted service is both a recurring cost and a single point of vendor control over the least replaceable data a person owns. Migrating away later only gets harder as the library grows.

Approach

A self-hosted Immich deployment: full library imported, mobile auto-backup pointed at it, and the search and album features the hosted product was being paid for. Containerised, staged on existing hardware first, and written to migrate onto a dedicated Linux host without a rebuild.

Technical decision

Prove the import before buying the server. The risk in a photo migration is the data — a decade of files with inconsistent EXIF, live photos and duplicates left by earlier backup tools — not the machine. Validating against the real library on hardware already owned meant the hardware specification followed evidence rather than guesswork.

Outcome

Live and serving the full library, with mobile backup running against it.

Stack

  • Immich
  • Docker
  • Linux
  • Self-hosted storage
  • Mobile auto-backup

Web AppsLive

NeoPDF

A self-hosted PDF toolkit covering the everyday Acrobat tasks — free to use, and no document ever leaves the machine.

  • Self-hosted
  • Local processing
  • No upload
  • Free

Read the case study

Problem

The operations people actually need — merge, split, reorder, sign, compress — sit behind a subscription, and the free web alternatives require uploading the document first. For files carrying signatures, invoices or identity documents, that is not an acceptable trade.

Approach

A PDF toolkit that runs entirely on the user's own machine: self-hosted, browser-based, no account and no upload step. The file never leaves the computer it started on.

Technical decision

Self-hosting is the product, not a deployment option. A privacy policy cannot be verified by the person relying on it; an architecture in which nothing is transmitted can be. That constraint gave up the conveniences a server would have provided, which is exactly why it is not negotiable later.

Outcome

Live and in use — free, self-hosted, no account required.

Stack

  • Self-hosted
  • Local processing
  • PDF toolkit
  • No upload, no account

Web AppsLive

Cerulean Arena

A physics-driven browser game — real vehicle dynamics, no install and no engine runtime in front of it.

  • Three.js
  • cannon-es
  • Vite
  • WebGL

Read the case study

Problem

Browser games usually trade away either fidelity or immediacy — a download on one side, an experience that feels scripted on the other. The target was WebGL-quality physics reachable from a link.

Approach

Vehicles accelerate down a runway, launch from curved ramps and attempt to reach defenders on a floating platform; overshoot and the far runway lets you turn around, leave the platform and the run ends. Three.js handles rendering, cannon-es solves the vehicle physics, Vite builds it.

Technical decision

Trajectories are solved, not animated. Scripted arcs are cheaper and repeat identically; delegating to a physics solver makes every landing emergent and moves the work to tuning mass, friction and ramp curvature. The simulation produces the variance that makes a second run worthwhile.

Outcome

Live and playable in the browser, with the source public.

Stack

  • Three.js
  • cannon-es
  • Vite
  • WebGL

Web AppsLive

nb.com — NB.OS

This site. A portfolio built as a desktop operating system — no framework, no build step, no dependencies to install.

  • Vanilla JS
  • No build step
  • Three.js
  • Canvas

Read the case study

Problem

A portfolio asserts capability; it rarely demonstrates it. A list of projects tells a reader what someone claims to have done. The page itself should be the evidence.

Approach

A bento landing that signs into NB.OS — a desktop with draggable windows, switchable wallpapers, a Windows/mac skin toggle, an interactive globe, a terminal, sixteen working dev tools and a printable resume. Vanilla HTML, CSS and JavaScript throughout. Three.js and globe.gl load from a CDN on demand, only at the moment an app requires them.

Technical decision

No build step, deliberately. A framework would have accelerated the window manager and guaranteed the site's decay — a lockfile that stops resolving in two years. Plain files remain openable indefinitely, and the constraint required writing the window manager, theme engine and canvas renderer directly rather than importing them.

Outcome

Live. Window manager, theme engine, wallpaper renderer and sixteen tools, with no dependencies at build time.

Stack

  • Vanilla HTML/CSS/JS
  • No build step
  • CSS design tokens
  • Canvas
  • Three.js on demand
  • globe.gl

Web AppsLive

PS5 Controller Tester

A single HTML file that diagnoses stick drift and dead inputs. Nothing to install and nothing to trust.

  • Gamepad API
  • Single file
  • Zero dependencies

Read the case study

Problem

Diagnosing a gamepad fault normally means installing software of uncertain provenance to answer a five-second question about hardware already in hand.

Approach

A one-file gamepad tester. Every button, trigger and stick axis responds live, with raw axis values displayed so drift reads as a number that will not settle rather than as a suspicion.

Technical decision

One file, no dependencies. The browser's Gamepad API already does the work; the engineering value is in adding nothing around it — no build, no bundle, nothing to install and nothing to trust.

Outcome

Live and self-contained, with nothing to maintain.

Stack

  • Gamepad API
  • Single HTML file
  • Zero dependencies