Sketchmind banner

Sketchmind

10 devlogs
64h 39m 52s

Sketchmind is an open-source collaborative whiteboard built for students who think visually. It gives you an infinite dark canvas with a handwritten aesthetic — draw, connect ideas with typed relational arrows, drop sticky notes, upload images, an…

Sketchmind is an open-source collaborative whiteboard built for students who think visually. It gives you an infinite dark canvas with a handwritten aesthetic — draw, connect ideas with typed relational arrows, drop sticky notes, upload images, and organize everything into frames you can present. Boards auto-save as you work and sync in real time with live cursors and presence, so studying with classmates feels genuinely collaborative. Built on Next.js 15, Excalidraw, Liveblocks, and Supabase — no paywalls, no installs, just a fast open-source thinking tool that lives in your browser.

This project uses AI

I used it for specific parts of the project: generating the initial Supabase schema as a starting point, the Liveblocks room auth endpoint boilerplate, and looking up Excalidraw API patterns I wasn’t familiar with yet.

Demo Repository

Loading README...

Fede Vitu

Shipped this project!

i built Sketchmind, a real-time collaborative whiteboard for students, with live cursors, board sharing, image uploads, PWA support, and a canvas that actually looks like my app and not just a wrapped Excalidraw. i’m a teenage developer from Argentina and i had 14 days, a rough idea, and way too much confidence. what followed was two weeks of fighting iOS install prompts, rewriting auto-save hooks, injecting custom styles into Excalidraw’s internals with MutationObservers, and somehow shipping real-time collaboration, database RPC functions, security hardening and a full PWA, most of which wasn’t even on my original roadmap. really proud of this one. sketchmind is out 🚀

Fede Vitu

Devlog #10 — this is it. sketchmind is shipped.

last update. and i’ll be honest, i almost didn’t make it. between school, homework piling up, and a deadline that was literally hours away, these last few days were a blur of staying up late staring at a canvas editor that kept finding new ways to surprise me. but here we are.

this final update is small but it matters. exports now always use dark mode by default, because who’s opening Sketchmind and switching to light mode? exactly. i also blocked external library imports from Excalidraw files, something i probably should’ve done earlier since letting users inject arbitrary library content into a collaborative board is the kind of thing that quietly becomes a security problem. a few more native Excalidraw UI elements got hidden so Sketchmind’s identity comes through clean. and if you close the Google popup mid-login, you now get a real message instead of nothing.

the README is done too. I’ll leave them below so you can see what the final product looks like. it’s the kind of documentation that makes a project feel real.

Flavourtown pushed me harder than i expected. i started this with a rough idea and a 14-day countdown and ended up building something i’m genuinely proud of — real-time collaboration, PWA, a canvas that actually looks like my app and not just a wrapped Excalidraw. I learned more in these months than in my entire life. if you made it this far following along, thank you. really.

sketchmind is out. go build something. 🚀

Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #9 — sketchmind is now an app. like, an actual app.

PWA is done. and i’m not going to pretend it was easy, because it wasn’t. converting a web app into something that installs natively, works offline, has shortcuts, icons at 15 different resolutions, and behaves differently depending on whether you’re on Android, iOS or desktop. iOS alone was a nightmare because Apple doesn’t allow automatic install prompts, so i had to build a manual step-by-step guide that appears when it detects Safari on iPhone. Android and desktop get the native banner. every platform has its own quirks and every quirk took time to figure out. there were moments where the service worker was caching the wrong version of the app and i was losing my mind trying to figure out why changes weren’t showing up. but it’s all working now. you can install Sketchmind on your phone, your laptop, your tablet, and it opens like any other app, no browser chrome, no URL bar. that’s a different feeling.

the save indicator also got a proper redesign. a floppy disk icon slides up from the bottom of the canvas while saving, then flips to a green checkmark on success or a red exclamation mark if something went wrong. it sounds like a small detail but when you’re drawing with someone else in real time, knowing your work is safe without having to think about it matters a lot. profile photos got one more improvement too. you can now delete your current avatar and go back to the default initials icon. the image processing pipeline also got smarter: uploads get cropped to 256x256 and converted to WebP right in the browser before they even hit the server.

one update left. then this thing ships.

Attachment
Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #8 — closing in on the finish line.

this update was mostly about fixing the things that were quietly annoying me. there was a horizontal scrollbar appearing on the right side of the screen exclusively on boards with Liveblocks active. not on the dashboard, not on the profile page, just the canvas. one of those bugs that’s completely harmless but impossible to ignore once you see it. gone now. also fixed a gap in the mobile styles where screens between 640px and 730px were falling through and rendering raw Excalidraw styles instead of Sketchmind’s. that range is basically every mid-size Android phone, so yeah, important.

the rename dialog got rebuilt from scratch. the old one was breaking on small screens and honestly didn’t look great to begin with. the new one is cleaner, has a 15-character limit with inline validation, and the keyboard actually focuses automatically on mobile when you open it. small thing, big difference. the back button inside the canvas editor also got redesigned. simpler shape, more on-brand, with a small icon animation that just makes it feel intentional. rate limiting is also in: magic link requests are now capped at 3 emails per 15 minutes per address, so nobody’s accidentally (or not so accidentally) hammering the mail server.

one more update left. i’m planning to convert Sketchmind into a full PWA, installable, with icons at every resolution, offline-ready. same as i did with Impostor-Game and StackNote. whether i get there before the event closes is the question. we’ll see tomorrow.

Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #7 — sketchmind is live. go leave your mark.

it’s deployed. like, actually deployed. not localhost, not a preview branch, the real production server on Vercel. getting there was its own fight: broken redirects, cookie issues, environment variables that worked fine locally and exploded on prod. the kind of stuff that’s impossible to debug without just pushing and seeing what breaks. but it’s all sorted now and the app runs exactly as it should.

since it’s live, i want to do something fun. if you’re reading this right now, open this link and leave your mark on the board: your name, an emoji, a drawing, a meme, whatever you want: https://sketchmind.fvitu.qzz.io/join/a7a798a6813ae7ea0d559b6438cabc24 (only if you have an account)

beyond the deploy, this update was a lot of smaller things that add up. the auto-save was rewritten from scratch, it now generates a “fingerprint” of what actually changed and only sends a patch to the database instead of the full board state every time. combined with a new Postgres RPC function that merges changes server-side in a single round trip, saves are now dramatically faster and way less noisy on the network (response time was reduced from 7 seconds to 900 milliseconds). the dashboard got a visual pass too: new empty states with custom illustrations for when you have no boards or nothing shared with you, a confirmation dialog before revoking share access (because that’s the kind of thing you really don’t want to trigger by accident), and search that filters correctly across both your own boards and shared ones.

mobile is finally fully responsive. the whole app, canvas included, works on a phone now. that one took forever.

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #6 — sketchmind is now multiplayer.

real-time collaboration is live. multiple people, same canvas, at the same time, cursors moving, elements syncing, selections visible, all of it. i knew Liveblocks existed but going from “i know what this is” to actually wiring up cursor tracking, element sync and presence avatars was a different story. understanding the mental model took a while. writing the code once i got it? surprisingly fast. i recycled a lot of patterns from earlier in the project and it clicked into place. the hard part was the race conditions: the canvas was trying to render before the Liveblocks room was ready, which caused some fun crashes. fixed that with proper loading states and now the join flow feels smooth.

pofile photos also got a real upgrade. before you could only paste a public image URL, which was janky and would randomly fail when external servers blocked the requests. now you upload directly from your device and it saves to Supabase Storage. and since presence avatars pull from your profile, yor photo now shows up live with your cursor when you’re in a shared board. that detail makes the collab feel way more human.

the magic link email was its own nightmare. i tried adding the Sketchmind logo to the template and every email client flagged it as spam. didn’t matter if it was an inline SVG or an img tag, instant spam folder. eventually figured out that pointing to a URL on the actual domain worked fine. also set up a dedicated Google account for the Resend sender so Gmail users see the Sketchmind logo next to the email. getting that verified without a phone Google would accept took longer than i want to talk about. mobile canvas styling is still a work in progress. it keeps breaking in creative new ways, but it’s further along than it’s ever been. big update. really proud of this one.

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #5 — sketchmind finally has a face.

the logo is in. took longer than i want to admit but it’s done — a pencil inside a borderless square with a light blue gradient, clean and minimal, exactly what i wanted. it shows up in the app header, in the browser tab, everywhere. no more default browser icon staring back at me every time i open a new tab. honestly something about having a real logo makes the whole thing feel more serious. like, it’s not just a side project anymore, it’s a product

most of this update was the kind of work that’s invisible when it goes right but brutal when it doesn’t. the entire app now has an error boundary at the root level — meaning if something crashes during render, instead of a completely blank white screen with zero explanation, you get a recovery screen with a button to reload. sounds small, but this is the difference between a project and something you’d actually ship to users. the auto-save logic also got stricter: before, if the server responded with an error but the fetch itself didn’t throw, the app would still mark the board as saved. that’s a silent data loss bug and i’m glad i caught it. now it actually checks response.ok before updating the saved state.

the canvas keeps getting more polished. there’s now a MutationObserver running to adapt the UI when you’re on a small screen — on mobile, the grid toggle button gets pulled out of the desktop toolbar and injected directly into Excalidraw’s bottom bar so it’s actually reachable with your thumb. syncing that button’s state with the real canvas state without it desyncing was more annoying than it sounds. beyond that, a big chunk of time went into index.css — touch targets, popovers, font pickers, arrowhead controls, the bottom toolbar — all of it got a pass to make it feel more consistent with Sketchmind’s visual language. It’s the styling work where an hour on three CSS lines yields a canvas that truly belongs to the app, not some dropped-in widget

Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #4 — the biggest update yet. sketchmind feels like sketchmind now.

okay this one took a while. like, genuinely the update i spent the most time on so far and it shows. most of it is visual but there’s real backend stuff in here too — the board limit is now enforced from the database directly instead of the app layer, which is cleaner and harder to bypass. 12 boards per user, no exceptions.

the home page got a full pass. sorting by last edit, by name, by creation date. a search bar that filters by exact board name match. also added a “Shared with me” section that doesn’t do anything yet, but the real-time collab update is coming and i want the structure already in place when i get there. on the canvas side, this is where the real work was — injecting custom styles into Excalidraw’s internals is genuinely painful. you have to figure out exactly which element you’re targeting, override the right selector, and make sure you don’t accidentally break something three components away. selection boxes are now light blue instead of Excalidraw’s default violet. sliders, buttons, side panel elements — all restyled to match Sketchmind’s look with rounded shapes and smooth animations. the context menu got completely redesigned too: dark background, each option has its own icon, and i removed a few things that didn’t make sense for this app.

also had a funny moment this update — i built a whole custom grid system that synced with the database, was pretty proud of it, and then realized Excalidraw already has a native grid mode that works better than mine and also saves automatically with the board state. so i deleted everything i built and just used theirs lol. sometimes the best code is the code you don’t write. still no logo btw. it’s becoming a running joke at this point.

Changelog

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #3 — phase 2. the canvas is real.

okay so. i was this close to shipping Tldraw — had it half integrated and everything — until i found out the production-ready version is paywalled. free tier wasn’t going to cut it. so i pivoted, went with Excalidraw, and honestly? best decision i’ve made this project. it’s open source, the integration was way smoother than i expected, and the moment i had it running inside Sketchmind i just sat there for a second because it looked exactly like what i had in my head from day one. that feeling doesn’t hit often.

the home dashboard got a full redesign. boards are sorted by last edited, each one shows a live Excalidraw thumbnail that renders on load, and the whole thing is wrapped in sketchmind’s color — light blue. every app i ship for Flavourtown gets its own color and this one felt obvious the second i tried it. also built a floating bottom nav bar inspired by iOS, very clean, two sections live right now (dashboard + profile). profile page renders your Google photo if you signed in that way, nothing crazy but it completes the loop.

the canvas itself has a custom side panel i built from scratch — background color picker using react-colorful, and a grid mode toggle that scales automatically with scroll. like a real graph paper notebook. every single change — board edits, profile updates, new boards — autosaves to Supabase in real time. no manual save button, no lost work.

what i thought would take me days took me a weekend. i’m not going to pretend that doesn’t feel good.

Changelog

Attachment
Attachment
Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #2 — the app is alive (kind of)

login works. like, actually works. Google OAuth, magic link via Resend, session handling, the whole thing. i basically transplanted the auth system from StackNote and Impostor-Game and adapted it here, which saved me probably a day of work. reusing your own code is genuinely underrated — why rebuild something that already works when the real challenge is the canvas editor sitting two phases ahead of me.

the home page is up too. you can create boards, they save to Supabase, they show up in the dashboard. it’s not pretty yet but the data layer is real and that matters more right now. the magic link email also got a redesign based on what i had in my previous project — cleaner, more on-brand. still no logo tho, that’s a debt i’m carrying into the next few days. sketchmind needs a face and right now it’s kind of faceless lol.

what’s missing is the thing that actually makes this app an app: you can’t open a board yet. you can create them, name them, see them in a grid — but clicking one does nothing. that’s the entire next update. getting the canvas loading from Supabase is the move. also i’ve been adding micro-animations everywhere because a stiff UI drives me crazy and i’d rather spend 20 extra minutes on transitions than ship something that feels like a prototype. almost there.

Attachment
Attachment
Attachment
Attachment
0
Fede Vitu

Devlog #1 — sketchmind starts now.

hey, first post here. i’m fede, and for the next ~12 days i’m building Sketchmind, a visual canvas. think excalidraw but made for students who actually want to think on a whiteboard, not just draw boxes. mind maps, real-time collab, study templates, the whole deal. i have less than two weeks to ship this and honestly that’s terrifying, but also kind of the point.

today was all setup. not the glamorous part, but the part that makes everything else possible. got Supabase configured with the full DB schema, wired up Google OAuth through Google Cloud Console, and set up Resend for magic link auth. i’m not starting from zero tho, i’m pulling patterns from my older projects and adapting them here, which is saving me a lot of time on stuff like auth that i really don’t want to spend 3 days on when the canvas editor is where all the interesting problems live.

one thing i’m doing differently this time: i dropped Next.js and went with Vite + Bun instead. every project i try something new, and this felt like the right moment to actually learn the stack properly rather than defaulting to what i already know. no turbopack, no app router, just lean and fast. we’ll see if i regret that in a week lol. setup’s clean tho, and the dev server starts in like 300ms which is already making me happy.

Attachment
Attachment
Attachment
Attachment
0