stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

Vensin

@Vensin

Joined June 6th, 2026

  • 17Devlogs
  • 4Projects
  • 2Ships
  • 31Votes
Hey, I’m Vensin — an anime enthusiast and developer who’s been coding for over 8 years. I’m based in Germany and love building projects that combine creativity, APIs, and interactive systems.
Open comments for this post

1h 25m 16s logged

Hello again my little Stardancers ✨inkan 0.6.0 is out, and this one was a big one. The plan was simple to say and hard to do: make inkan faster than Fastify on plain node:http, without generating code at runtime the way Fastify does with new Function. I wrote a plan with phases, measured main before touching anything, and then went through it step by step, keeping only what the numbers carried.First the fixed costs. Every request used to make about twenty little objects where six would do, and the request id came from a random UUID. Now the id comes from a counter, everything a route can work out ahead of time is worked out once at start, and a request with a body is only routed once. That alone saved about four percent of CPU per request. Then something odd happened: over HTTP, under full load, it was ten percent slower, even though it spent less CPU. I spent a good while hunting that down, measuring one change at a time against the last one, and it turned out to be fields I had made lazy. Filled on first use, they cost more under load than they saved. Made at once again, and the ten percent were back.Then the schemas. Every schema now checks through one function made once from its rules, which I call its stamp, instead of walking the schema tree on every request. To make sure nothing changed, a test builds every schema twice, once the old way and once the new, and compares two thousand random schemas and values. Same values, same messages, same paths.Writing answers was the lesson of the week. My first idea was a writer in plain JavaScript that writes only what the contract lists in one pass. It was clean, and it was almost twice as slow as the native JSON.stringify. So it went. What stayed: a plain object that holds exactly what the contract lists goes straight to the native writer, and anything else is copied with only the declared fields first. While pinning the old writer down with tests I also found five places where it wrote something it should not have, and two of them could let a key the contract never listed slip out. All five are fixed.And the honest result: on the bench inkan 0.6.0 scores 89.1 against Fastify’s 88.6, with node:http as 100. That is level, not ahead, because the runs overlap, so I am not calling it faster. It is 5.5 percent faster than 0.5, and with inkan seal a body of 50 objects is checked faster than by any server on the bench. Every number, phase by phase, is in the repository, including the ideas that did not work.There is more than speed in this one. The context can answer with text, html, a redirect or a 404 now, and the html tag escapes everything you put into it, so a name someone typed can never become a script on your page. Layouts work per scope, cookies are safe by default, and a handler can hand back rows straight from a database cursor: they go out as they are read, each one trimmed to the contract, as JSON or as one line per row. ctx.csv writes a million rows without holding them in memory, ctx.signal stops a query when the client leaves or the time is up, and a route can cache its answers and ask the database once when ten people ask at the same time.The website got a new logo too, 印 between braces, and the docs now have a real API section with every method and every option in one place.Next up is winning the scenarios where Fastify is still ahead: small requests, the router and middleware. I have a few ideas.See you next time ✨

0
0
9
Open comments for this post

1h 8m 19s logged

Hello again my little Stardancers ✨ It’s devlog time, and this one comes with a confession: I moved a real app onto inkan.

Not a todo list. A real one with 55 routes, file uploads, backups of a couple hundred MB, sessions and a mail setup. It ran on Express, and I wanted to know what happens when inkan has to do real work. Turns out: mostly fine. But not completely. And that “not completely” turned into inkan 0.5.0

The first problem was request bodies. inkan read every body into memory, with one 1 MB limit for the whole app. Fine for JSON, less fine for “hey, can I upload this 2 GB backup?” No ❤️ So I paused the migration and fixed the framework first.

0.5.0 brings t.binary() for files sent as the request body, and t.stream() for real streaming uploads: your handler gets the upload chunk by chunk, so the file never sits in memory. Limits are per route, so one endpoint can take 2 GB while the rest stays at 1 MB. On the way I found a fun bug: when a stream hit its limit, or the server answered 401 before the upload was done, the connection could just… hang. Fixed, the response arrives and the rest gets drained properly

Then the frontend. Now there’s serveStatic(): hashed assets cached for a year, index.html never stuck in a cache, and unknown routes fall back to the SPA. Except /api, where a typo gets a real 404 instead of your entire frontend 💅 compress() does Brotli and gzip, streams included. In the app I migrated, the bundle went from 75 KB to 18 KB.

There’s also ctx.ip for the login rate limiter (Bun and Deno too), per-route body limits and app.bodyFor() for adapter authors. And the benchmarks say no potato: every scenario stayed within ±4% of main on the same GitHub runner.

And then something else happened: inkan got integrations 🧩 All in one repo at github.com/inkanjs/integrations.

@inkanjs/vite runs your API inside the Vite dev server, so frontend and API share one port. No proxy, no second terminal, just npm run dev. The API reloads on every save, each reload counts as a fresh restart so your timers don’t multiply, the docs and inspector links show up in Vite’s banner, and a broken API shows up in Vite’s error overlay.

@inkanjs/next turns an inkan app into Next.js route handlers with one line, works with the Pages Router too, and has direct(app): a typed client for Server Components that calls your API in the same process. CI builds and starts a real Next.js app, because “works on my machine” isn’t a testing strategy.

@inkanjs/query is for TanStack Query: keys and types straight from the API paths, failed responses as errors with the problem document, and a retry() that won’t retry a 404 until the heat death of the universe.

@inkanjs/uws runs inkan on uWebSockets.js, with graceful shutdown and HTTPS, and it’s the fastest way to run inkan. Nuxt, SvelteKit, Astro and Remix don’t even need a package: app.fetch is enough, and the repo has recipes.

And the migration? All 55 routes run on inkan now, split into files by area instead of one 1300-line index.js. Every test passes, the frontend didn’t change a single line, and dev went from two processes, two ports and a proxy to npm run dev on one port. Express, compression and concurrently are gone, 74 packages fewer

A real project is great at showing you where your framework doesn’t hold up. inkan had a few of those places. Now it has fewer.

npm install @vxnsin/inkan@0.5.0

See you next time, Stardancers 🌙

0
0
29
Ship Changes requested

I rebuilt my personal site completely from scratch (vensin.dev v2). The old site had been sitting behind a maintenance page since September while I worked on this one.

The look is a cozy old-web style: pixel fonts, little windows with their own title bars, a starry sky in the background. The sidebar is the centerpiece and it’s genuinely alive. It shows my Discord status in real time, coding (with the project and file I’m working on), watching anime, listening to music, playing games, or watching YouTube, each rendered differently depending on what I’m actually doing. My Apple Watch rings show up there too, synced through a Shortcuts automation on my phone. There’s also a “today” widget and a live visitor counter in the footer.

The music page is more than just now-playing. Every 30 seconds the site polls Spotify and logs it, and I also imported my full official Spotify data export, so the yearly stats, top tracks, top artists and listening clock are based on real history, not just what the site has seen since launch. The anime page works the same way: a watch log scraped automatically, with weekly bars and badges for seasons I’ve actually finished.

The whole site changes with the calendar. Each season has its own particles and color palette, and certain days lock in a special look no matter what you pick yourself: Halloween, Christmas (with a sleigh flying across the sky), New Year, Valentine’s Day, my birthday, and April Fools, which breaks almost everything on purpose for one day.

There’s a guestbook with spam and keyword filtering plus a honeypot field, and a contact form that pings me directly on Discord with buttons to approve or reject what came in. Everything on the site, messages, gallery, projects, and a cache of everything pulled from outside APIs, lives in one SQLite file, and a background scheduler keeps that cache warm so visitors never wait on an external API. Nightly backups get encrypted and shipped off-site automatically.

My pixel cat Mochi lives in the sidebar and reacts to what I’m doing. She dresses for the season, falls asleep in the browser tab icon when you switch away, and has her own idle clicker game complete with a shop, upgrades, achievements, and a prestige system. There’s also a hidden moon scene easter egg somewhere on the site that I won’t spoil here.

The hardest part was keeping everything in sync without it turning into a mess: one database backing the entire site, a scheduler that refreshes different data on different intervals, and a Discord activity system built so that adding support for a new app is just dropping in one small handler file. Getting the whole thing ready to self-host on a Raspberry Pi, including its own Impressum and a proper cookie consent flow, was also its own project on top of everything else.

What I’m proud of: there’s no tracking, no ads, it’s fully self-hosted on my own hardware, and it actually feels alive instead of being a static portfolio page. To test it, sign the guestbook, poke Mochi in the sidebar, click into the music and anime pages to see the real live data, and try changing the season picker in the footer.

  • 5 devlogs
  • 8h
Try project → See source code →
Open comments for this post

16m 52s logged

Hello my little Stardancers ✨

Devlog #5 for vensin.dev v2: this one’s all about Mochi, my pixel cat, who has quietly become the most work-intensive feature on the whole site.

First, the anime page got a real watch log. Every episode gets pulled in automatically and turned into weekly bars, a “finished lately” row, and badges for seasons I’ve actually completed, not just started and abandoned like a coward. Then Mochi herself got proper outfits: a flower for spring, sunglasses for summer, a scarf and witch hat for autumn/Halloween, a santa hat for December, and party hats with actual confetti on special days. Hats sit on her ears now instead of floating above her head like she’s being haunted.

Then I got distracted and gave her an entire idle game. Click Mochi, buy her upgrades, the upgrades make more mochi while you’re gone, and when the numbers get silly you spend one of her nine lives to prestige and start over with permanent bonuses. There’s a shop, achievements, and a golden mochi that shows up at random for a bonus. I will not be taking questions about how long I spent balancing the math on this.

And somewhere in the code there’s a keyboard shortcut that triggers a full-screen moon scene with two people standing on the ground watching it rise. Find it yourself 🫡

0
0
14
Open comments for this post

16m 5s logged

Hello my little Stardancers ✨

Devlog #4 for vensin.dev v2: the site started celebrating holidays without asking me first.

The whole look now follows the calendar. Spring gets sakura petals, summer gets fireflies, autumn has leaves tumbling down, winter gets pixel snow sitting on top of every window. Visitors can override it in the footer if they want a different season than the real one. But a few days of the year lock the look no matter what you pick: Halloween gets ghosts and a cobweb, New Year gets fireworks, my birthday gets confetti, Valentine’s gets pixel hearts, and Christmas gets a full sleigh with two reindeer flying across the sky plus presents falling between the snow. April Fools is its own chapter: the title flips upside down, the cursor turns into a rubber duck, buttons physically dodge your mouse once, and the date claims it’s March 32nd. I will not apologize for any of this.

The site can also talk back now. There’s a guestbook with spam filtering (links, slurs, keyboard mashing, a honeypot field bots can’t resist filling in) and a contact form that pings me directly on Discord with a button to approve or reject what came in, so I don’t have to open the admin panel just to read a message. And since all of this now lives in one SQLite file, I added nightly backups: a compressed copy gets made automatically, encrypted, and shipped off to an offsite file host, so a dead SD card can’t just erase the whole site.

0
0
7
Open comments for this post

16m 12s logged

Hello my little Stardancers ✨

Devlog #3 for vensin.dev v2: the music page, and the boring stuff that makes the fun stuff work.

First the boring part, I promise it’s short. Everything on the site now lives in one SQLite file: messages, gallery, projects, and a cache for everything the site pulls from outside. A little scheduler runs inside the server and refreshes the data on its own: Discord every minute, GitHub every hour, anime posters every hour, and so on. A page view never has to wait for GitHub or Spotify, it just reads from the database. Fast for you, cheap for me.

Now the fun part. The music page shows what I’m listening to right now, with the cover and a progress bar. But I wanted more than “now playing”, I wanted stats. So every 30 seconds the site asks Spotify what’s playing and writes it down, and that turns into hours listened this year, my most played tracks and artists, and a listening clock that shows at which hour I listen the most. Spoiler: it’s 10 PM, and it’s a lot of System Of A Down.

The problem was that the site only counts from the day I turned it on. So I added an import for Spotify’s official data export, and now the yearly stats are real instead of “you listened to 4 songs in 2026”. Spotify then tried its best to break everything: podcasts that aren’t songs, local files with no cover, and a playlist field that got renamed. All handled now, and I’m only a little bit traumatized.

0
0
12
Open comments for this post

18m 35s logged

Hello my little Stardancers ✨

Devlog #2 for vensin.dev v2, and the site finally has a face.

I went full old-web: pixel fonts, little windows with traffic-light buttons, a starry sky in the background, and at first even cherry blossom petals floating around. I removed those after they kept drifting next to the title and looking like dead pixels. All the icons are pixel art too. I first traced the Steam logo by hand three times, and when it still looked like a potato, I switched to a proper pixel icon set.

The real star is the sidebar, because it’s alive. The Discord window shows what I’m doing right now. If I’m coding, you see the project, the file and how many errors VS Code is yelling at me about. If I’m watching anime, you see the show and the episode. If I’m on YouTube, there’s a progress bar. If Discord reports something the site doesn’t know yet, it sends me a DM so I can teach it. Below that, a “today” window flips between the date and the time in Tokyo, and my Apple Watch rings show up as little pixel rings, so now the entire internet can see whether I closed my move ring today. Bold of me, I know.

Next devlog: the music page, the anime log, and everything that keeps the data running behind the scenes 🫡

0
0
21
Open comments for this post

2h 9m 14s logged

Hello again my little Stardancers ✨

inkan 0.4.0 is out, and I closed the entire milestone in one day. Every single issue. I don’t know who I am anymore either.

The one I’m proudest of: npx @vxnsin/inkan learn. It’s a tutorial that lives in your terminal. It sets up a tiny tea shop, gives you twelve quests, and checks your work every time you hit save. Forgot a validation rule? It tells you. Stuck? Press h for a hint, press it again for a less subtle hint. By quest 12 you’ve built routes, contracts, auth, hooks, plugins, and you’ve broken a client on purpose (for science). No other web framework ships a tutorial inside itself, so I figured: why not be the first one.

inkan also got grown-up stuff this time. Hooks, plugins and decorators, so you can bolt on your own things without touching the core, and a little rate limiter built on exactly those APIs to prove it works. Routes can now live in a folder tree, routes/teas/[id].ts and friends. And inkan finally leaves the house: app.fetch runs it on Bun, Deno and serverless, workers: “auto” uses every CPU core you own, and there’s an adapter for uWebSockets.js if you want to go absolutely feral.

Then there’s inkan seal. It stamps your contracts into plain code ahead of time, so big requests get checked in about half the time. No eval, no runtime magic, just a file you can actually read. And if your contract changes and you forget to reseal, inkan notices and quietly ignores the stale seal. It’s basically a very responsible goldfish.

Speed check, because I promised honest numbers: on a fair benchmark inkan beats Hono, by 0.4 points. I’m choosing to celebrate that like it’s 40. Fastify is still a bit ahead, Express is still Express. But put inkan on the uWS adapter and it’s a third faster than plain Node itself. Who’s the framework now.

Also: inkan moved into its own home at github.com/inkanjs, and routes can now say who’s allowed in (security: “bearer”) and actually mean it.

0
0
12
Open comments for this post

2h 25m 54s logged

Hello again my little Stardancers ✨

inkan 0.3.0 is out, and it has learned to read the room. Specifically: it now notices when you’re about to break things for everyone who depends on you. Which is more than I can say for some group projects.

The big one is inkan diff. You give it the OpenAPI document from your last release and your app as it is now, and it tells you exactly which changes would make your clients cry. A field that suddenly became required? Breaking. A route you “cleaned up”? Very breaking. A new optional field? Totally fine, go off. Put it in CI and your pipeline turns red before your users do.

Also new: npx @vxnsin/inkan examples drops a whole explained project into your folder. Six of them, from “hello” to “deploy”, each with a README that tells you what to read first and a list of ways to break it on purpose, because honestly that’s how we all learn anyway. There’s a typed client now too: your frontend gets its types straight from the server routes, no codegen, no ritual sacrifices. Typo in a path? It doesn’t compile. Beautiful.

And the rest of the goodie bag: server-sent events with a schema per event (even endless streams can be tests now, don’t ask how, it’s magic and also a counter), file uploads with size and type limits, examples that build on each other (“create a tea, then fetch it”), request ids in every log line and every error, a replay button in the inspector that turns real traffic into examples, and you can now edit requests right on the docs page. Huge thanks to AndrewCMD for dates, refinements and recursive schemas, inkan’s brain got noticeably bigger.

0
0
28
Open comments for this post

18m 53s logged

Hello again my little Stardancers ✨

inkan 0.2.0 is out, and it has trust issues now, just like my ex. The difference is that inkan’s trust issues are actually helpful.

The big one: inkan check now tells you what you forgot to test. If your route promises a 409 but none of your examples ever triggers it, inkan points at it and says “that one, nobody checked that one.” Add –strict and your CI refuses to go green until you write that example. Your docs page shows the same hint, so the lie gets caught twice.

Browsers can finally talk to inkan from another origin too. There’s a little cors() middleware, and OPTIONS requests get answered automatically instead of a sad 405. The terminal got its colours, RinZ27’s lifecycle hooks made it in, and the CLI now has real tests of its own. Releasing is one click now as well: a GitHub release publishes to npm with a signed link back to the exact commit, so you can check that what you install is what’s on GitHub.

0
0
34
Open comments for this post

7h 13m 58s logged

Hello my little Stardancers ✨Welcome to the very first devlog of vensin.dev “sakura” v2! So, I already have a portfolio. It works, it’s fine, and I don’t like it anymore. It looks like every other developer portfolio out there: a hero section, a “hi, I’m a developer” line, some project cards, done. Nothing about it feels like me. So instead of fixing it, I’m doing the most developer thing possible and rebuilding the whole thing from scratch. The idea is a cozy old-web corner of the internet, like the personal sites from back when people made websites just for fun, mixed with a healthy dose of anime energy: pixel fonts, little windows, a starry sky. And it should feel alive. When you visit, you should see what I’m listening to right now, what I’m watching, what I’m coding, and maybe find a few secrets I’ve hidden around. Less “please hire me”, more “come hang out in my room”. The old site goes into maintenance mode while I build, so the pressure is on.

(project is already done, but i post it to show the creation process of making the portfolio bc i forgot to put it on stardance)

0
0
18
Open comments for this post

24m 14s logged

Hello my little Stardancers ✨

Devlog time! No ship yet, but here’s what’s been cooking.

inkan (印鑑) is an API server for Node where the docs can’t lie. Every route gets one contract, and from that inkan validates requests, types your handler, writes OpenAPI and serves docs.

The fun part: every example in the docs also runs as a test, so if your code drifts away from what the docs promise, inkan check goes red before anyone reads a lie. Zero dependencies, so your node_modules can finally rest.

This week I merged my first community PR 🎉 It adds lifecycle hooks for connecting your database on startup and closing it cleanly on Ctrl+C. Before merging I caught two sneaky bugs: a failing startup hook took the whole server down, and a stuck shutdown hook could keep the process alive forever, like a guest who won’t leave the party. Both are fixed and tested.

Next up is better logging, and then the ship is coming soon™ 🫡

0
0
14
Ship Changes requested

Venix is a Slack bot built with Node.js and Slack Bolt that lets users search for anime and characters using the Jikan API.

It provides interactive Slack commands like anime search, character lookup, and random anime generation with structured results, images, and buttons for deeper details.

Try project → See source code →
Open comments for this post

56m 50s logged

Devlog – Venix Slack Bot

I’ve been working on this project quite a bit recently and testing different ideas for how to structure a Slack bot that connects with the Jikan API.

At this point, the core features are basically done.

The three main commands are now finished:

/anime-search lets you search for anime and shows detailed information like rating, episodes, status, genres, and the cover image.
/character-search returns a list of characters based on the query, ordered by relevance, with the ability to open detailed views through interactive buttons.
/random-anime generates a random anime recommendation, currently filtered to prefer higher-rated entries and formatted with key information.

Right now the project is in a stable state where all core functionality is working as intended. The interaction flow with Slack blocks and buttons is also in place.

Next step will likely be improving the architecture.

After that I plan to run it on a Raspberry Pi for always-on hosting.

0
0
2

Followers

Loading…