# Zain Wania

Senior Staff Engineer. I build AI agents that help care coordinators match patients with caregivers.

Hi, I'm Zain — a Senior Staff Engineer at Caribou based in Toronto. I build AI systems that help care coordinators match patients with caregivers, with an eye toward user experience and long-term maintainability. My current work uses Vapi, the AI SDK, and an agent-memory module I designed and built.

- Location: Toronto, Canada
- Email: zain@wania.dev
- GitHub: https://github.com/ZainW
- LinkedIn: https://linkedin.com/in/zainw

## Experience

### Caribou
- Senior Staff Engineer (2026-05 to present): Building AI systems that help care coordinators match patients with caregivers using Vapi, the AI SDK, and an agent-memory module I designed and built.

### ContactMonkey
- Staff Engineer (2024-04 to 2026-05): Architecting systems and setting technical direction for a ~20-person engineering organization. Co-architected the AI email checker; independently designed and built the internal knowledge base agent and MCP server.
- Technical Lead (2022-02 to 2024-04): Led the frontend platform team and drove design system adoption
- Senior Software Engineer (2019-10 to 2022-02): Core contributor to the product's Vue.js frontend and internal tooling

### Ample Organics
- Software Developer (2018-01 to 2019-09): Built the Vue.js frontend, introduced E2E testing, and established the component library from scratch

### Exact Media
- Full Stack Developer (2016-02 to 2017-04): Full-stack development across client projects with Rails and JavaScript

## Selected work
- Agent memory for care coordination (Caribou, 2026): A memory module for Caribou’s care-coordination agents, which run on Vapi and the AI SDK. I designed and built it.
- Replacing a 15MB calendar with 76KB of our own (ContactMonkey, 2026): Ripped out Bryntum Calendar for an in-house component, with a rough internal Claude plugin doing a lot of the migration work. /blog/killed-15mb-calendar-dependency-with-claude-plugin
- Knowledge-base agent and MCP server (ContactMonkey, 2024–26): Designed and built on my own: an internal agent over the company’s knowledge base, plus an MCP server so other tools could use it.
- AI email checker (ContactMonkey, 2024–26): Co-architected the AI email checker as Staff Engineer for a ~20-person engineering organization.
- Frontend platform and design system (ContactMonkey, 2022–24): Led the frontend platform team and drove design system adoption across the product.
- Mdow (Side project, 2026): A calm desktop reader for markdown folders, with an AI companion that cites its sources. /projects/mdow
- zstack (Wania Labs, 2026): An opinionated TypeScript product starter: Cloudflare-first, TanStack Start, and Alchemy. https://github.com/Wania-Labs/zstack

## Stack
TypeScript, StyleX, Node.js, Fastify, Tailwind CSS, AWS, Alchemy, Docker, PostgreSQL, Vapi, AI SDK

## Open to talking about
- Creating a design system: Building cohesive, scalable component libraries that unify your product experience.
- AI for engineers and beyond: Introducing AI-powered workflows for engineering teams and the broader organization.
- An internal AI knowledge base: Making your team’s collective knowledge accessible and searchable through AI.

# Projects

## zstack
Source: https://github.com/Wania-Labs/zstack

Opinionated TypeScript product starter from Wania Labs. Cloudflare-first, TanStack Start, and Alchemy.

## Mdow
Source: https://zainwania.dev/projects/mdow

A calm desktop app for reading markdown and asking AI questions about files across a folder. Mdow connects to your existing OpenCode setup over ACP, with local context and clickable source citations.

I built Mdow to make local markdown folders easier to read and understand. It combines a focused cross-platform reader with an AI companion that connects to existing OpenCode providers over the Agent Client Protocol.

## The problem

Markdown files often contain the durable context behind a project: plans, architecture notes, documentation, and decisions. Editors are optimized for changing those files, but not always for settling in and reading across a folder.

Mdow separates that reading experience from the editor while keeping files local and compatible with the tools developers already use.

## The approach

The AI companion is read-only by design. It builds context from the active document, the open folder, and explicitly tagged files, then sends that context through an installed ACP provider. Responses include citations so an answer can be checked against its source.

Because provider access comes from OpenCode, Mdow does not need another model account or a separate API-key workflow. It can use the providers and subscriptions already configured on the machine.

## Capabilities
- Ask questions about the focused document, an open folder, or explicitly tagged files
- Use existing AI providers configured through OpenCode and ACP
- Follow clickable citations back to the source markdown
- Render code with Shiki and diagrams with Mermaid
- Browse folders, tabs, recents, and document outlines in a focused desktop interface

## Stack

TypeScript, React, Electron, TanStack, OpenCode ACP, md4x, Shiki, Mermaid, and a separately distributed native macOS beta.

# Writing

## Build Today, Learn Tomorrow: In Defense of the Slop Fork
Published 2026-04-02. https://zainwania.dev/blog/build-today-learn-tomorrow-in-defense-of-the-slop-fork

Streamdown is a small, clean renderer for streaming markdown, the kind you need the moment you put an LLM response on screen. It exists for React. It doesn't exist for Vue. If you're building in Vue and want the same thing, your options are to stitch together Stack Overflow answers, write it yourself, or go without.

I picked a fourth option. I forked it, pointed AI at it, and had a Vue port working by the end of the afternoon.

The code isn't beautiful. I didn't write every line, and I couldn't defend every decision in it from memory. By most people's definition it's a slop fork.

It also works, and before that afternoon nothing did.

---

## Two kinds of slop

Slop earned its reputation. GitHub is full of AI-generated repos that are half finished and wrong in ways you only find out about in production. Someone thought "I could make a tool for that," let a chatbot do the rest, and walked away. Nobody reviews it or maintains it, and it collects stars from people who assume it's useful.

That's one kind. The other kind fills a gap that was actually there. The first is noise. The second is an unglamorous fix for a real problem, and I think we keep lumping the two together.

The Vue port is the second kind. Vue apps render streaming markdown too, and now there's a library for it.

---

## The order of operations flipped

What interests me more is what AI did to the sequence.

It used to be that if you wanted to build something you didn't understand, you were stuck. You had to learn enough to build it first. So the thing got built slowly, got built badly, or didn't get built. Learning was the price of admission.

Now you can reverse it: get the thing working, then go back and understand what it's doing. You still do the learning. You just do it with a working program in front of you instead of an empty file.

For niche work like ecosystem ports, which nobody is going to write a polished library for, that matters a lot.

I don't have perfect command of every part of the port. I understand it well enough to use it, debug it when it breaks, and improve it over time, which is more than I knew before I built it. "I used AI to build this" and "I don't know what I built" are further apart than people assume.

---

## The fine print

None of this means AI-generated code is fine. Plenty of it isn't. You still need to know enough to judge what you got back, to notice when it's subtly wrong, and to make the tradeoffs yourself. AI doesn't replace that judgment. It lowers how much you need to know before you can start.

What it gives you is permission to solve your problem today and let your understanding catch up tomorrow.

Vue needed a Streamdown port, and now it has one. It's a slop fork, it works, and I'll take that trade.

## The Effort Didn't Disappear — It Changed Shape
Published 2026-03-28. https://zainwania.dev/blog/the-effort-didnt-disappear-it-changed-shape

There's a kind of product showing up everywhere now, and you can recognize it before you can say what's wrong with it. The landing page is clean and says nothing. The app works and solves a problem nobody has. The design is polished the way a stock template is polished: technically correct and empty. It was made in a weekend, and you can tell.

AI made it possible to go from an idea to *something* faster than ever. But something isn't a product, and the distance between the two is growing.

---

## Typing was never the hard part

The misconception I keep running into is that AI removed the need for skill. What it removed was the need for typing.

Knowing the syntax for a React component was never the bottleneck. The work was knowing why state should be split a certain way, when a component is doing too much, and which abstraction will hurt you in six months. The code on screen was just the output of that thinking. AI can produce the code. It can't do the thinking for you.

Design is the same. AI will give you a layout in seconds. Knowing that users will miss your call to action because the visual hierarchy is fighting itself comes from reps: shipping things and watching real people use them.

## You don't need six books anymore. You still need to learn.

The old route into building things was a grind: a seven-hour YouTube tutorial, five Udemy courses, three Stack Overflow threads from 2014, and a book that was out of date by the time it was printed. All of that just to get started.

AI really did change this. You can scaffold a project, generate the boilerplate, and get past a syntax error in seconds instead of an afternoon. The barrier to entry dropped, more people can build, and more ideas get made. That's a good thing.

Somewhere along the way, though, "lower barrier" got read as "no barrier." People skipped the learning and went straight to shipping, and what they shipped was functional and forgettable.

The learning was never only about being able to write code. It was how you developed taste and judgment, and a feel for what users need as opposed to what sounds great at 2am. You can shortcut the mechanics. You can't shortcut the judgment.

## Experience still compounds

AI multiplies what you already have, and a multiplier is only as good as the number it's multiplying.

Take a senior engineer who understands system design, has been burned by bad abstractions, and knows what simple actually means. Give them AI and they get alarmingly fast without losing quality. They hand off the tedious parts and spend the time they save on architecture, edge cases, and the small decisions that separate software that works from software people love.

Give the same tools to a beginner and they ship faster too, often in the wrong direction. They generate code they can't debug and features they can't extend, and they pile up technical debt at a pace that used to take a whole team months.

The difference between those two outcomes is whether someone did the learning or skipped it.

## The last 40% is the product

This part is counterintuitive. AI was supposed to close the gap between idea and product, and in one sense it did. In a more important sense it widened it.

Everyone gets the first 60% now. Scaffolding, boilerplate, and the MVP shell are table stakes. The remaining 40% is where the product lives: the polish, the coherence, and the decisions that make it feel intentional. That 40% still takes what it always took, which is skill, taste, experience, and effort with no shortcut.

More people than ever can get to almost done, and fewer seem to push past it.

## The effort changed shape

I'm not arguing against AI. I use it constantly, and it's the best thing to happen to my workflow in years. I use it the way a carpenter uses a nail gun, to go faster at work I already know how to do. You wouldn't hand a nail gun to someone who can't find the studs and expect a house.

Typing every character is worth less now, and that's fine. Knowing *which* characters to type, why, and how they fit into a system that has to hold together is worth as much as ever, probably more. When anyone can produce output, what sets you apart is whether your output is any good.

The effort didn't disappear. It changed shape. The people who use AI to extend their skills rather than replace them are the ones building things worth using.

Everyone else is just generating.

## Replacing a 15MB Calendar Dependency With 76KB of Our Own
Published 2026-03-22. https://zainwania.dev/blog/killed-15mb-calendar-dependency-with-claude-plugin

Some UI libraries cost money, fight every style change you make, and weigh more than all of your app's feature code put together. Ours was Bryntum Calendar. After months of putting up with it, we took it out.

This is how we did it, and why the scrappiest tool I own turned out to be the most useful part of the job.

---

## Calendars in Vue are rough

The decision to use Bryntum only makes sense once you've looked at the alternatives.

If you need a full-featured calendar in React, you have real choices. FullCalendar has solid React support and the path is well worn. In Vue, and especially in Nuxt, it's grim. You search and find libraries whose last commit was in 2021, wrappers around jQuery plugins, and "Vue adapters" that were clearly bolted on after the fact. The TypeScript support runs from grudging to decorative, and getting an event handler to do something useful means learning three layers of someone else's abstractions.

So picking Bryntum wasn't naive. It was one of the few options that actually worked.

It is full-featured. Recurring events, drag and drop, and resource views all come in the box. The problems showed up a few months in:

- **Styling.** Bryntum has its own theme engine, its own CSS variables, and strong opinions about how everything should look. Making it match our design system meant overriding generated class names and hoping nothing else moved. We weren't customizing it so much as arguing with it.
- **Types.** The TypeScript support felt like an afterthought, and autocomplete gave out right when we needed it.
- **Cost.** It's a paid license. That's fine when you're getting value from it. It's harder to justify when a ten-minute CSS change takes two hours.

Then we asked the question we should have asked at the start: **what are we getting for 15MB?**

A Gantt chart renderer, resource histograms, a spreadsheet module, and a full enterprise scheduling engine, as it turned out. Bryntum isn't really a calendar. It's a scheduling platform that has a calendar in it, and we were using maybe 10% of what we shipped while the rest rode along in our bundle.

Our replacement is **76KB**. That covers event rendering, date navigation, and grid layout. We didn't do anything clever to get there. We only built what we needed.

---

## Building the replacement

We already use Nuxt UI across the codebase, so the buttons, inputs, dropdowns, and popovers were there. The calendar-specific logic turned out to be the smaller part of what Bryntum was doing for us. We built the calendar pieces ourselves on top of components we already trusted. It takes styling without a fight and matches the design system because it's made of the design system. There are still edge cases to iron out, but it's ours.

The part I'm proud of and a bit embarrassed by: I used my own Claude Code plugin to help with the migration.

It's called [auto-research](https://github.com/ZainW/ai-plugins). The idea isn't new. It traces back to Andrej Karpathy's thinking on autonomous, research-driven coding, then to [pi-autoresearch](https://github.com/nicholasgasior/pi-autoresearch) as an early implementation, and then to [this tweet from Tobi Lütke](https://x.com/tobi/status/2032212531846971413). Tobi ran `/autoresearch` against Shopify's Liquid codebase and got 53% faster combined parse and render time with 61% fewer object allocations. His verdict: "This is probably somewhat overfit, but there are absolutely amazing ideas in this." That was enough for me to start building my own.

Running `/research <task>` kicks off six steps:

1. Parse the task.
2. Spawn three to five subagents that investigate approaches in parallel, using web search and codebase analysis at the same time.
3. Synthesize and rank what they found.
4. Implement the top approach with Claude Opus.
5. Verify the result against your toolchain.
6. Auto-fix failures, up to a configurable retry limit.

It also saves session state, so an interruption doesn't throw away the work.

For the migration, I used it to do the thinking up front. Instead of digging through Bryntum's event model by hand to work out which Nuxt UI components could replace what, I described the task and let the subagents go wide. What came back was a ranked list of approaches with real reasoning about the tradeoffs. Because the research had actually been done, the implementation went more smoothly.

It isn't production grade. "Scuffed but useful" is accurate, and that's a perfectly good kind of tool to have.

---

## AI is putting pressure on bad software

The broader point is that plenty of the component libraries teams have been locked into for years aren't good. They were the least bad option back when building an alternative was slow and expensive. Switching cost a lot, building cost more, and mediocre software kept collecting license fees.

AI changes that math. It doesn't write perfect code. It is good at producing UI components that look clean, are properly typed, and are styled the way you want. The gap between using the library and building your own used to be huge, and it's closing fast, especially on styling and visuals, which is where many of these libraries have always been weakest.

That's real pressure on component vendors. If your moat is "we did the hard work so you don't have to," and the hard work is measurably easier now, you need another reason for people to pay you. We asked a simple question about our bundle, didn't like the answer, and replacing the library turned out to be far smaller than it would have been two years ago.

None of this means you should build everything yourself. Sometimes the library really is the right call. But the bar for replacing one has dropped, and some libraries that used to clear it easily don't anymore.

The plugin is at [github.com/ZainW/ai-plugins](https://github.com/ZainW/ai-plugins) if you want to try it. Keep your expectations modest. It's a work in progress, like the rest of us.

# Uses

## Hardware
- Apple MacBook: My main machine for development and daily work.
- Framework Desktop: Running Fedora Linux. For when I want full control over the hardware.
- 5K Monitor: Easy on the eyes for long sessions.
- NuPhy Air75 V3: Low-profile wireless mechanical keyboard. Great for both the desk and on the go.
- Logitech MX Master: The best mouse for productivity. Scroll wheel alone is worth it.
- AirPods Pro 3: Daily drivers for focus and calls.
- KEF LSX II LT: Compact wireless speakers. Surprisingly good soundstage for the size.

## Software
- Cursor: Where most of the work happens. Editor and agents in one place.
- Claude Code: AI coding agent. Still the one I reach for in a terminal session.
- Grok Bot: For thinking and writing outside a repo. Faster than spinning up a coding agent.
- OpenCode: AI coding agent in the terminal.
- Ghostty: Fast, minimal terminal emulator.
- Helium Browser: Lightweight browser, mostly for focused browsing sessions.
