VeckaJul 2026 to now8 min read

Vecka, the workspace I kept rebuilding until it became a product

Founder & Product Engineerproductivityai assistantsolo build

I founded Vecka and I am its only builder. It started as a module of my personal dashboard and became a live React and Node.js workspace with tasks, notes, Google Calendar, Gmail and an assistant that edits through the same actions I do.

Role
Founder & Product Engineer
Period
Jul 2026 to now
Team
Founder and only builder
Stack
React 19, TypeScript, Vite, Node.js, SQLite, Gmail and Google Calendar APIs, Caddy on a self-managed VPS
AI in the loop
Claude Code and Codex to build, OpenAI API inside the product, Playwright agents to verify

01 · Why

I kept rebuilding the same tool for myself

Vecka did not start as a startup idea. It started as the thing I kept rebuilding for myself. The first version was a Next.js finance hub. In June 2026 I rewrote it from scratch and opened the brief with one line, a central dashboard for me personally, rebuilt clean. The core of it was my own task system, modelled on how Things works, because I wanted to understand the model well enough to build it rather than depend on it.

By late July that dashboard ran on my own server at daviddn.cloud, with tasks, a calendar and mail as modules beside everything else in my life.

On July 31 I looked at the workspace module and decided it was the part worth more than a personal tool. I pulled it out as its own product. The first job was to strip out everything that was mine, the server panel, my name, my data, and replace it with a fictional person and a fictional week, so a stranger could open it and see a product instead of my life.

On August 26 it moved to vecka.ai under one name. Vecka is Swedish for week. I later dropped the tagline about your week, because nothing in the product stops at a week, and settled on the one it has now, everything you are working on, in one place.

The bet is simple. Every tool I use now has its own assistant, and each one only sees its own slice. The to-do is in one app, the email that created it is in another, the meeting it depends on is in a third. If they share one window, the assistant can see all of it, and so can I.

A central dashboard for me personally, rebuilt clean.

My kickoff brief for the dashboard rebuild, June 2026

A central dashboard for me personally, rebuilt clean.

02 · Split screen

Two apps side by side, moving like one surface

The first product decision was the layout. Tabs hide context, so Vecka shows any two apps side by side. You can right-click an app in the rail and open it left or right, drag a page by its title to one side, or pick an app for an empty half.

I cared about how it moves as much as what it does. When a pane opens, each side holds its content at the width it will land on, so nothing reflows while it travels, and the old layout dissolves into the new one.

The calendar was the hardest part. An early version could show half of a day at the edge of a narrow pane, which reads as broken. I set a rule and rewrote the layout to hold it. The pane is shared among whole day columns that clear a 120 pixel floor, and the last column ends exactly at the edge.

Then I profiled a two second divider drag in Chromium. 1.8 seconds went to raster, ten times any other pane. Drawing the hour rules as a repeated one pixel tile instead of a stretched gradient cut raster to 550 milliseconds. A per frame follow that costs one width read and two writes took the partial column during a drag from 13 to 101 pixels down to 0 to 2.

The empty half needed a job too. Dragging a page by its title splits the window and leaves a picker in the other half, and the rail marks which app sits on which side.

Vecka Tasks inbox full screen. The cursor right-clicks Calendar in the sidebar, chooses Open on the right, the window splits into Tasks and a week calendar, then the calendar pane is closed and Tasks glides back to full width.
Opening Calendar beside Tasks, then closing it. Both panes travel as one surface (demo data).

raster in a two second divider drag
1,344 to 550 ms
hour rules drawn as a one pixel tile
partial column per frame
13 to 101 px, now 0 to 2
one width read and two writes per frame
minimum day column
120 px
the pane is shared among whole days only

03 · Projects

Projects as the spine across Tasks, Mail and Calendar

The second decision was structural. A project in Vecka is not a folder inside one app. Mail threads are filed to it, events belong to it, to-dos sit under it, and every surface draws the same short tag, like NWv2 or COMP 210.

The project page is where that pays off. It opens with what is due next, the next event and unread mail, then the tasks under their headings, a one week agenda, the filed threads and the notes.

I kept filing deterministic wherever I could. A suggestion is matched to a project by its sender and subject against the open projects’ tags and names, never by reading the body, and a model is only asked when that match is unsure. In that lane 61 percent of verdicts need no model call at all.

The spine only works if the apps underneath are real. Mail is a full Gmail client with rich bodies, compose and true send, and full history lives in per workspace SQLite archives. When I moved to that design I checked all 3,697 original messages against the working set plus the archive and found none missing.

The calendar syncs every Google calendar and edits Google events natively, but it is local first. An event added while Google is busy or disconnected stays on the grid and waits in a queue, instead of vanishing.

04 · Suggestions

Suggestions you approve, edit or dismiss where you work

With consent, Vecka reads incoming mail and proposes to-dos and calendar blocks. My first version drew them in a strip above the list and it read like a notification feed. I made each suggestion a row of the list instead, the same shape as a to-do on a light blue wash, with the checkbox as Approve.

Nothing lands in the list or on the calendar without that click.

Every row carries approve, edit and dismiss. Edit opens a card with the deadline, a project picker and a line back to the email it came from. An edit is saved onto the suggestion, so it stays a suggestion until approved. The deadline flag counts down in days, turns red on the day, and switches to hours when the to-do has a time today.

The list itself had to feel physical. Rows reorder with a live drag. The carried row lifts as its own copy and the rows below slide one row out of the way. The gap kept flipping every other frame until I measured geometry from rest positions at the lift instead of from boxes in mid transition.

05 · Assistant

An assistant that edits through the same actions I do

The decision that shaped the assistant is that it never writes to the data directly. Its edits run through the same client-side actions as my clicks, so every change it makes lands in the same undo history and comes back out the same way. The model proposes, the product applies.

Anything that writes appears first as an approval card that states the change in the product’s own terms. If I switch conversations mid turn, the turn is parked with its open cards and resumes when I come back, so an approval is never silently dropped.

Responses stream over server-sent events, with the tool work drawn above the answer. Every call goes to an append-only usage ledger priced per model, and an operators’ portal shows spend, tokens and cache hit rate. Splitting the prompt into a cached system part and a per turn context part keeps repeat calls cheap.

I pick the model per task by cost and fitness. Chat titles moved to a smaller, cheaper model, while the assistant stayed on the stronger one.

Mail gets stricter rules. Emails are treated as data and never as instructions, no subject or body is ever logged, and every AI feature over mail sits behind one consent switch. Vecka asks Google for gmail.modify and never for full mailbox access.

06 · Front doors

A homepage and a demo that show the product instead of describing it

vecka.ai used to redirect straight to a sign-in card, so a stranger learned nothing. I gave it a homepage on September 15 and rebuilt it several times in a week, each time closer to showing the real product.

The version live now is one pinned scroll stage. Fourteen real tool marks float in depth, then curve into one point, and the Vecka window fills in behind them.

The hero window is a faithful miniature of the app, drawn from the real screens’ measurements, and it walks its apps once with the product’s own pane motion. I ported the page to React components, prerendered at build time. Full React DOM put the largest paint on a mid tier phone 348 milliseconds behind the static page, so the browser runs the same components on Preact, which brought it level.

The mark changed twice. I turned down a letter in a tile early and drew a V instead. In September I explored three symbol directions and picked Gather, three rounded forms around an open centre, because it kept its opening clearest at 16 pixels.

The public demo is the second door. A visitor types a first name, picks one of four personas, and lands in a full workspace seeded with 40 to 70 records per module, dated relative to the moment they arrive. The rule I hold myself to is that every feature ships with its demo data in the same change.

07 · How I build

Shipping with agents, and a gate I do not skip

I build Vecka with Claude Code and Codex. My job is the product call and the review. I write the direction, agents build on a branch, independent critic agents review the result, one writer applies the fixes, and I look at it on the live URL before it counts. When the work does not meet the bar, I say so and it goes back.

The rule that keeps this honest is the gate. Every deploy installs, typechecks, runs the unit suite, builds, runs the browser suite against an isolated copy that cannot reach real data, ships, then signs in with a throwaway account to check the live app.

Agents also do the looking. One pass photographed every surface at widths from 1920 down to 320 pixels, then fixed the shared system for phones with a bottom tab bar, sheets and 44 pixel touch targets. Real Playwright in a real browser verifies each change, because a preview pane that never paints once let a real bug ship.

Speed has a cost, and I paid it. On September 12 a cleanup step in my own deploy tooling expanded an unset variable and deleted the account store. I restored it the same night from a backup plus 3,426 intact documents recovered from the raw disk.

Then I made sure it could not happen quietly again. The store takes a verified snapshot every hour, a deploy refuses to ship without one under a day old, deletes under the store are refused on the box, and the server will not boot if the account count falls below half of the last boot.

DateMilestone
Jun 16, 2026Dashboard rebuilt from a clean brief, with my own task system
Jul 31, 2026The workspace module becomes its own product
Aug 25, 2026Production serves the React app, Google sign-in
Aug 26, 2026The assistant launches, the product becomes Vecka on vecka.ai
Aug 31, 2026Mail assist and the public demo at demo.vecka.ai
Sep 11, 2026Projects become the spine across apps
Sep 12, 2026Store restored the same night, four guard layers added
Sep 15, 2026Homepage, suggestion rows, live drag to reorder
Sep 22, 2026Split motion, a calmer project page, the homepage in React
From my dashboard to vecka.ai

08 · What I learned

Building for one person first, and then for a stranger

The biggest change in me was the audience. For months I built for exactly one user who knew where everything was. Making it a product meant a stranger had to open it cold and understand it, which is why the demo, the seeds and the homepage exist at all.

I also learned that motion is part of the product. Most of the passes on the split screen and the calendar were not features. They were the difference between an interface that jumps and one that holds still while you work.

The honest part is that Vecka has no users yet beyond me and demo visitors. Agents made output cheap, which made it easy to skip the question of whether a change mattered. So I now write the goal and what would prove it before I start. Next are Google verification, which lifts the cap and weekly expiry on an app in testing, and shared workspaces for teams.

Archive

More from the project

  • Vecka Tasks inbox in dark mode with the sidebar of areas and projects, a lists column, and the inbox showing two suggested rows, loose to-dos, and project blocks with deadline flags.
  • The Vecka sidebar with Home, Tasks, Notes, Calendar, Mail and Chats, where Tasks and Calendar both carry a small window icon showing which side of the split they occupy, followed by areas and projects.
  • A single calendar day column for Tuesday the 22nd with an hour gutter, stacked colour coded events, and a now line at 8:34.
  • A Choose an app panel with six buttons, Home, Tasks, Notes, Calendar, Mail and Chats, and the hint Drag an app to a side to split the window.
  • vecka.ai hero with the headline The agent that knows you, Get an invite and Try the demo buttons, and a Vecka window showing notes and a calendar week for a sample company, over a night sky.
  • The vecka.ai homepage stage on a phone, app icons converging into a scaled Vecka window as the page scrolls.
  • Two looping homepage cards. Replies in your voice shows three drafted replies to an email and one being sent. Meetings that book themselves shows a meeting request placed into a free afternoon slot.
  • Two looping homepage cards. To-dos that write themselves adds rows pulled from mail and notes, sorted by due date. Nothing goes quiet drafts a follow-up to an unanswered thread.