Focused on large-scale graphics rendering, visualization engines, graph editors, and end-to-end engineering. All open-source code is public and all demos run live in the browser.
Renderer-agnostic rubberband selection & multi-drag engine
Grew out of AntV X6 issue #4823. It splits batch dragging into three clean parts: rAF coalescing (many pointer events collapse into one computation per frame), a drag snapshot (no repeated model reads mid-drag), and a preview / commit split (visual feedback decoupled from state commits).
Problem it solves: frames dropping after ~100 selected elements. Works with any graph editor and binds to no renderer.
Zero-dependency SVG graph-editing kernel
2,108 lines, written from scratch: semantic pins (direction / side / role / hot zone), orthogonal obstacle-avoiding routing, snapping, an undo stack and JSON persistence.
Verifiable: 49 unit tests plus 2 Chrome E2E suites, all passing.
Port-editing plugin for AntV X6
Adds visual port-editing to AntV X6. The change landed in the X6 main repository as feat: add port editor plugin.
Why it matters: not "I have sent PRs" — I can modify someone else's core engine and get it accepted.
Grid GIS workbench with an AI agent
Vue + deck.gl rendering 1,327 real-scale sites. Ships a runnable AI agent: a Node-side ReAct loop with an 11-tool registry (data queries, BFS connectivity, map actions) streaming over SSE, with 5 end-to-end acceptance scripts passing.
Problem it solves: letting users drive map data in natural language instead of walking ten levels of menu.
The first six share one deterministically generated 20,000-node dataset, each rendered with a different engine; the seventh is a different kind of build — a complete editing application; the eighth inverts the format into a render benchmark, putting four rendering approaches on the same data so the numbers can be re-run. Every one of them opens and runs live in the browser — these are not recordings. The first six also have walkthrough videos.
20,000 nodes / 36,610 links. Tiled mode delivers the first screen in 1.62 MB across 16 tiles; full-dataset mode pulls 8.86 MB in 53 ms. Both hold 60 FPS. A live inspector shows visible tiles, transferred bytes and per-request timing.
42 linked sites: instanced rendering via InstancedMesh, glow with no post-processing pass, bezier link arcs with animated particles, and raycast picking that returns an instanceId straight into the data model. 60 FPS / 83 draw calls.
500 vehicles moving live, with trail history, geofenced zones and live occupancy counts, and click-to-inspect. Positions update every frame; trails are sampled at 400 ms — 60 FPS.
Component designer and assembly canvas: semantic pins, connection-policy validation, orthogonal obstacle-avoiding routing, command-based undo/redo. A stress-test button generates 2,000 nodes and holds 60 FPS; 211 unit tests pass; the bundle is 130 KB (36 KB gzipped).
Upload a GLB and artwork, click the model surface to place a decal that conforms to the geometry via DecalGeometry rather than floating in front of it, then drag, resize, rotate, manage layers, undo and export an image.
The same dataset as demo 01 rendered on a Cesium globe — one dataset, two engines. All detail levels (Backbone / Regional / all 20,000 nodes) hold 60 FPS, with no ion token and no imagery-provider dependency, and click-to-locate on any node.
The floorplan is data — change floorplan.json and the house changes, with no code edit. 24 furniture SKUs over 28 real CC0 models. Dragging snaps to a grid and to walls, furniture can stack, and an illegal drop is pulled to the nearest legal spot with a footprint marker. Variants, colour and material swaps, a bill of materials with a running total, saved scenes with version-conflict handling, first-person walkthrough and HDRI lighting — all of it on one undo history.
Six locally generated signals with four independent options: Canvas 2D, tuned ECharts, naive ECharts and experimental WebGL2. Supports 100k to 1M historical points, streaming updates, full-history review and JSON export. The write-up compares Canvas 2D and WebGL measurements, drawing approaches and timing boundaries.
All data is synthetic or CC0; every reload reproduces the same scene, and the network demos carry live frame-rate counters. The links open straight away — no login, no install.
Small things that do not belong on a CV, but say something: I like building tools. When I hit a problem I would rather write the tool than work around it — even at 2am.
Rust + WebAssembly image compression
Written to cut image bandwidth: the Rust side compiles to WebAssembly so images are processed in the browser and never leave the machine. Ships as a web app plus a CLI and a Vite plugin.
Rust CLI for port inspection
Checks port usage and the owning process, with single-port and range scans, timeout and concurrency control, and result export. Cross-platform across macOS / Linux / Windows.
Still maintained: after a Linux build failure was reported, the root cause was found and fixed (the branch returned 0 when the system assigned the port), and CI on the pull request is running again.
Interaction-phase comparison tool
Splits an interaction into start / update / finish / cancel and visualises the four phases side by side — because the most common cause of a drag bug is that those four phases were never separated.
| Project | Contribution |
|---|---|
| Varlet | Vue 3 mobile component library — organisation member; submitted and maintains changes to input, field-decorator, ellipsis and date-picker |
| AntV X6 | Graph-editing engine — port editor plugin merged into the main repository, plus documentation and fixes |
| Element Plus | Table multi-select filter, scrollbar transition fixes |
| antdv-next | Component fixes and documentation improvements (11 merged — my highest count) |
| vercel/ai | OpenAI provider and codemod changes |
| Others | plotly.js, recharts, deck.gl, naive-ui, vexip-ui, Pyomo, PyPSA, PowerGridModel, Grid2op, pandapower, litellm, cline, OpenHands, modelcontextprotocol |
94 pull requests submitted (48 merged), across 39 repositories, plus 122 issues filed. All of it is searchable on GitHub under @william-xue.