Austin Shijo

epestrmTvare6iitk · statistics · ’24–’28

I build desktop tools for people who live in their terminal and have a sustained graphics tilt.

About

I'm a sophomore at IIT Kanpur studying statistics, and a secretary at the Programming Club. Online I'm epestr most places and mTvare6 on GitHub.

What I build, mostly: developer tools and desktop utilities for power users — window managers (enki), virtual filesystems (ghfs), terminal UIs (ssr, coxide), language tooling (tjit), real-time audio pipelines (loom). Things you'd reach for if you spent your day in a tiling WM and tmux. Plus a sustained graphics tilt — path tracers, GPU agent simulations, the tooling and rendering work on Graphite, which runs through the second half of this page.

Most of what I write is in Rust, some C/C++, Python, Lua, GLSL/WGSL/Slang as the project demands. What follows is organised by domain, with the desktop / devtools stuff up front and the graphics work after. For the chronological one-pager, see the resume. For things I've written, see the blog.

Now

Graphite

Contributor — Graphite Editor Rust · wgpu · Vello · ~25k★

github.com/GraphiteEditor/Graphite · May ’25 – Sep ’25

Got into Google Summer of Code 2025 to work on Graphite, the Rust 2D graphics editor. 45+ merged PRs across the editor and its rendering stack. The work covers a few different areas of the codebase:

  • Bitmap caching layer. Replaced the editor's base64-encoded SVG image-data path with one that uses the JS Reflect API to offload pixel data to an off-screen HTMLCanvas. Severely cuts the editor↔preview transfer cost; the UI stutter that came with large bitmaps went away.
  • Masking architecture. Redesigned how arbitrary vector data gets masked. The new path routes between fast <clipPath> and the more general <mask> tag based on a performance heuristic, and supports inverted masking, dynamic stroke alignment, and custom paint ordering. The luminance-based clipping that powers part of this got upstreamed into Vello (the 2D renderer Graphite is migrating onto), and I led the editor's core pipeline migration to Vello v0.5.0 + WGPU v25 to keep upstream parity and unlock the new luminance capability.
  • Transformation pivots. Built a Blender-style pivot system: each layer carries an independent internal origin coordinate, and the Select / Path tools support Active Object and Average of Origins pivot modes, switchable mid-edit.
  • Hierarchical selection. Selection now uses Least Common Ancestor traversals over the layer tree to implement shallow- and deep-click heuristics and parent-child collapsing, with tolerance-aware lasso polygon boundary tracking.
  • The long tail. Transform-cage hit-testing, node deserialization lifecycles, persistent isometric workspace grids, undo-stack correctness on tool transitions — the 30-odd smaller bugs you find when the surface is being used.

Desktop & window managers

enkiwm Rust · Smithay · Wayland

An experimental Wayland window manager built on Smithay. The interesting bit is the input model: a Alt_R toggle drops the compositor into a vim-style modal mode. From there HJKL moves a virtual camera over an integer grid, UIOP shifts focus between cells, Shift+UIOP swaps the windows in two cells, Shift+HJKL grows the camera span, and Alt_L+HJKL shrinks it. New windows snap to the nearest empty cell (BFS from the camera origin). The grid is a HashMap<IVec2, Window>.

picom-shaders GLSL

Updated GLSL shaders for the picom X11 compositor — the upstream community shader repos had bit-rotted against newer picom versions, so this is a clean set that actually compiles.

Filesystems

ghfs Rust · fuser · Tokio

A read-only FUSE filesystem that exposes GitHub as a directory tree. Mount it, cd /tmp/github/torvalds/linux, and cat fs/fuse/file.c works. Built on the fuser crate's experimental AsyncFilesystem trait via the Tokio adapter, so the kernel can sit on a FUSE syscall while we go round-trip to api.github.com without blocking the runtime.

The inode table is a HashMap<u64, Node> behind an RwLock with an AtomicU64 for new inode generation. Directories carry a DirKind tag (Root / User / Repo / Standard) and a hydrated flag — readdir is what triggers the GitHub API call, using git/trees?recursive=1 so a whole repo arrives in one shot. File contents live behind Arc<OnceCell<Vec<u8>>> and the read path drops the read-lock before the network call, so a slow blob doesn't freeze the rest of the FS. A GITHUB_TOKEN bumps the rate limit from 60/hr to 5k/hr.

Languages & Compilers

tjit Rust · Cranelift

A statically typed systems language with a JIT compiler. The pipeline is hand-rolled lexer → recursive-descent parser → typed HIR with an explicit type-checker pass → Cranelift IR via cranelift-jit. cranelift-module resolves libc and host symbols (print_i64, print_str) as Linkage::Import; the JIT writes machine code into executable pages and I transmute the entry point to fn() -> i64.

The most novel bit is the arbitrary-width integers. Types like u1, u3, i17, i42 are first-class. In a struct BitPack { is_active: u1, day_of_week: u3, count: i17 }, each field gets a bit-offset, fields are packed contiguously without crossing 64-bit hardware boundaries, and the codegen emits a load → unsigned right shift → mask, plus a sign-extending shl/sshr pair for signed widths to promote them to native register size for arithmetic. Storage-narrow, compute-wide.

Supports algebraic data types (struct + payload-carrying enums laid out as a 32-bit tag + bit-packed payload), pattern matching with ranges (0..10, 10..=20), destructuring, and wildcards. Match compilation generates a recursive decision tree of basic blocks: each arm has its own fail-block that falls through to the next, with a final trap UnreachableCodeReached at the end. Fixed-size arrays, a pipeline operator (x |> f(args) desugars to f(x, args)), explicit primitive casts, and string literals as 16-byte fat pointers (rodata pointer + length) round it out. Heap FFI, an affine type system, RAII, and a real borrow checker on a custom MIR are next.

Terminal tools & CLIs

coxide C

A minimalist zoxide in C: keep a frequency table of directories you've cd'd into at $XDG_DATA_HOME/coxide/main.csv, pick the most-used substring match. The binary itself is small — coxide shell <name> emits the appropriate o() wrapper for bash / zsh / fish / elvish / xonsh / PowerShell. One of my older projects, from before IITK.

sscli & ssr C · Rust · ratatui

Two takes on student-search for IITK — one is a pipe-friendly C CLI with grep-able output and an fzf + ueberzugpp wrapper that previews student photos in the terminal; the other is a full ratatui TUI in Rust with regex-filterable form fields and inline image rendering via Sixel/Kitty/iTerm protocols (with a chafa-style fallback for Alacritty).

kbdgen Python · simulated annealing

Optimises keyboard layouts for a given corpus by simulated annealing. Cost is a weighted sum of finger-travel distance, same-finger bigram penalty, same-hand bigram penalty, per-finger effort (calibrated by finger CPM), and per-row effort. Adaptive swap count: the perturbation strength scales with temperature, so it explores aggressively when hot and tunes finely when cold.

cypercine C

A tiny hyperfine-style CLI microbenchmarker in C. Runs each command n times, aggregates timing statistics, and tells you which is fastest. Process control via raw fork/exec, timing via clock_gettime.

tch Rust · crossterm

A tiny CHIP-8 emulator that runs in your terminal — a parser that decomposes opcodes (x, y, n, nn, nnn) into a Message enum, a state machine that interprets them, and a crossterm-driven 64×32 display at ~500 Hz. The CHIP-8 keypad is mapped to the standard QWERTY 1234/QWER/ASDF/ZXCV block. Following Cowgod's reference. Later got reused as the reference architecture for PClub's Systems Spring Camp.

htBrowser Electron · JS · archived

A keybind-summoned mini browser for reading docs while you code. The hotkey opens a different URL based on which window is focused, via a per-WM_CLASS table in $XDG_CONFIG_HOME/htBrowser/config.json. Archived early ’25, the idea works, but I found them to be useless once I started using a tiliing wm and Linux.

Audio & DSP

loom Rust · PipeWire · DSP · egui

A real-time spatialiser for PipeWire. It exposes a loom_virtual_sink (the capture side of a paired PipeWire stream); you wire your system mix into it through qpwgraph, the playback side feeds the hardware out, and the egui window has a single intensity dial.

The DSP path is the part that took the longest. From input to output:

  • Three-band split via cascaded Linkwitz–Riley 4th-order crossovers — each LR4 is two LR2 / Butterworth-Q biquads in series, giving the complementary phase response that lets the bands sum back flat. Splits at 120 Hz and 4 kHz.
  • Low band → mono. Below ~120 Hz, wavelengths are longer than the head, so directional cues don't really exist and summing avoids the cancellation you'd otherwise get when the stereo image is widened later.
  • Mid band → head-shadow crossfeed. A short delay line into a −12 dB high-shelf at 700 Hz models the acoustic shadow of the head: the contralateral ear hears a slightly delayed, treble-attenuated version of the opposite channel.
  • High band → mid/side. The mid (M = L+R) gets a pinna notch (a −6 dB peaking EQ at 7.5 kHz) and a 0.15 ms microITD on the centre channel. The side (S = L−R) goes through two modulated all-pass decorrelators with out-of-phase LFOs (2.5 ms ± 0.5 ms @ 0.15 Hz on one channel, 3.1 ms ± 0.7 ms @ 0.11 Hz on the other) — small fractional-delay drift that breaks mono coherence without sounding chorused.
  • Transient-aware width. A peak envelope follower (1 ms attack, 50 ms release) tracks the mono mid; on a transient, the side gain is throttled down so a snare hit doesn't smear stereo. The side is then waveshaped with x − x³/3 for soft saturation instead of hard clip.
  • Early reflections. A 6-tap delay per channel with asymmetric prime delays (7, 13, 19, 23, 31, 41 ms left; 11, 17, 29, 37, 43, 47 ms right) and a per-tap one-pole low pass for air absorption — later taps roll off harder.
  • Stereo room tail. A Schroeder-style reverb: four parallel comb filters with asymmetric prime delays (29.3 / 37.1 ms left, 31.7 / 41.9 ms right) and a damped feedback path, then one static all-pass per channel for late diffusion. The L and R sides are cross-mixed at 30% before the combs so the energy circulates between channels rather than developing as two independent reverbs.
  • Final mix. dry + 0.7 × ER + 0.15 × tail per channel, all scaled by the intensity dial. Below intensity ≤ 0.01 the whole engine is bypassed so the audio thread does no work.

Graphics & GPU

griw Rust · wgpu · Slang

A real-time path tracer. Shaders are written in Slang and compiled to SPIR-V at build time via a build.rs that shells out to slangc; the runtime is wgpu over Vulkan. Up to 64 bounces per pixel, Lambertian / Metal / Dielectric materials, progressive accumulation across frames into an Rgba32Float radiance texture, and ACES filmic tonemapping on output. WASD plus mouse-look for the camera, with a sample-counter reset on movement. The Slang side uses generics, Optional<T>, and methods — much nicer than writing this in WGSL.

wants Rust · wgpu · WGSL compute

A 65,536-ant pheromone-trail simulation, all on the GPU. Three pipelines per frame: a process pass that decays and blurs the pheromone texture, a compute pass that updates each ant (workgroup_size(64), sensing left/forward/right with a 3×3 kernel and steering by gradient), and a render pass that samples the world. Two ping-pong Rgba8Unorm textures swap roles each frame so reads and writes never collide; red and blue channels carry the away-from-home and going-home pheromones, green carries food. Inspired by Sebastian Lague's video, but the wgpu plumbing is mine.

nbody Rust · Barnes–Hut

5,000-body gravitational simulator with a quadtree-based Barnes–Hut O(N log N) approximation (θ = 0.4) and Plummer softening to keep the field finite at small radii. Tree storage is an arena (Vec<QuadNode> + index handles) so children are co-located in memory and there are no Rc cycles. Integration is leapfrog (v += ½(a_prev + a)·dt; r += v·dt + ½·a·dt²), which is symplectic and so doesn't drift the orbits the way Euler does. Renders to a velocity-coloured 2D grid via the pixels crate at a stable 60 FPS.

lenia C++ · ArrayFire

Bert Chan's original Lenia rules in 80 lines of C++ on top of ArrayFire — the continuous-space, continuous-time generalisation of Conway's Game of Life. A bell-shaped 2D kernel (R=13, scaled to integrate to 1) is convolved with the world, the result is mapped through another bell-curve growth function (μ=0.150, σ=0.015), and the world steps with A += G/T, clamped to [0, 1].

physarum C++ · OpenGL · GLSL compute

100,000-agent slime-mould simulation modelled on Physarum polycephalum. Two GLSL compute shaders alternate each frame — agents sense pheromones at three angles, steer toward the strongest, deposit their own; the trail map then decays and box-blurs. Multiple parameter presets (linear, grainy, moldy, wormline, solid_turbid_milky) give very different aesthetics from the same underlying model.

Famous-on-the-internet, qualified

hello-world.rs Rust · satire · ~3.6k★

🚀 Memory safe, blazing fast, configurable, minimal hello world written in rust(🚀) in a few lines of code with few(1247🚀) dependencies🚀.

Generic types nested past comedy, CI, Docker, Nix flakes, AUR PKGBUILD, a Windows manifest, ~1000 transitive crates, a few hundred PRs of people gleefully adding more. It is the most popular thing I've ever written and it should not be on a serious resume.

Other open source

Tools I reach for

primary
Rust
also
C/C++, Python, Lua, Vimscript, Java, R, GLSL, WGSL, Slang, JS/TS, shell
compilers
Cranelift (jit, module, codegen), hand-rolled lexers and parsers, typed HIR, ADT layout, pattern-match compilation, bit-packing arithmetic
systems
FUSE (fuser) with Tokio async, libc FFI, X11, Wayland (smithay), Linux audio (PipeWire, libspa-sys)
audio / DSP
Linkwitz–Riley crossovers, biquad EQ design, Schroeder reverbs, head-shadow crossfeed, decorrelating modulated all-passes, transient detection, mid/side
graphics
wgpu / WebGPU, Vello, compute pipelines, ping-pong textures, path tracing, Slang→SPIR-V, OpenGL compute, ArrayFire, picom shaders
tooling
git, GitHub Actions, Cargo, Make, CMake, Nix, Arch makepkg, Docker, neovim

Education

IIT Kanpur — B.S. in Statistics & Data Science, 2024–2028. CPI 9.2 / 10.0; recipient of the IIT Kanpur Academic Excellence Award (top 10% of the cohort, 2025-26), and a perfect 10.0 / 10.0 SPI in the 2024–25 even semester. Programming Club secretary for the current year — introduced the Graphics domain, authored the Graphics and Systems roadmaps from scratch, led a 10-day Graphics Spring Camp as instructor (walked the campers through a GPU path tracer modelled on griw), and contributed tch as the reference architecture for the Systems Spring Camp.

Around the web