DEV Community

Cover image for I got bored of SaaS dashboards, so I built a Matrix-style Terminal UI instead (Next.js + Framer Motion)
DK
DK

Posted on

I got bored of SaaS dashboards, so I built a Matrix-style Terminal UI instead (Next.js + Framer Motion)

How I built a retro-futuristic CLI interface for my new startup using HTML Canvas and React.

Most B2B SaaS landing pages look exactly the same in 2025. You know the vibe: simple gradient text, a glassmorphic dashboard screenshot, and "Enter your email" CTA.

I wanted to build something for developers. And developers live in the terminal.

So for my new project, s33d (a gamified team recognition protocol), I decided to ditch the standard UI libraries and build a fully interactive Terminal Interface with a "Digital Rain" background effect.

Here is how I built it using Next.js 14, TypeScript, and Framer Motion.

1. The Matrix "Digital Rain" Effect 🌧️

I wanted a background that felt alive but didn't chew up 100% of the CPU. I used the HTML5 API for performance.

The trick is to treat each "drop" as a column.

// Simple effective matrix rain logic
const draw = () => {
  // Semi-transparent black fill to create "trails"
  ctx.fillStyle = 'rgba(0, 0, 0, 0.05)'; 
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = '#22c55e'; // Green text
  ctx.font = `${fontSize}px monospace`;
  for (let i = 0; i < drops.length; i++) {
    // Random character
    const text = chars[Math.floor(Math.random() * chars.length)];
    ctx.fillText(text, i * fontSize, drops[i] * fontSize);
    // Reset drop to top randomly
    if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
      drops[i] = 0;
    }
    drops[i]++;
  }
};
Enter fullscreen mode Exit fullscreen mode

Pro tip: Using rgba(0, 0, 0, 0.05) for the background fill instead of clearing the canvas is what creates that cool fading trail effect.

2. FLIP Animations for the "Stock Market" 📈

The core concept of s33d is that it's a "Stock Market for Team Culture." You invest "seeds" (kudos) in your teammates, and their value goes up.

To make the numbers tick up and down like a real trading terminal, I used Framer Motion.

<motion.span
  key={value}
  initial={{ y: 20, opacity: 0 }}
  animate={{ y: 0, opacity: 1 }}
  exit={{ y: -20, opacity: 0 }}
  transition={{ duration: 0.2 }}
>
  {price}
</motion.span>
Enter fullscreen mode Exit fullscreen mode

This simple AnimatePresence wrapper makes the numbers slide in/out smoothly whenever the data updates via Supabase Realtime.

3. The Interactive Terminal ⌨️

The hero section isn't just a video—it's a playable demo. You can actually type commands like:

🌱 @sarah great work on the backend fix!
./current_portfolio
./market_status
I built a custom command parser that regex-matches user input and simulates a server response. It feels like SSH-ing into a server, but it's all client-side React state.

Why I built this?

I realized that most recognition tools (giving kudos/praise) feel like a chore because the UI is boring.

If we want engineers to actually celebrate each other's work, we need a tool that feels like it belongs in their workflow. That's why s33d lives in Slack, and the dashboard looks like Hacker Typer.

Live Demo

You can check out the live effect here: s33d.sh

I'm currently running a Lifetime MVP Deal (basically offering it for free to early beta testers because I need feedback on the terminal UX).

Let me know what you think! Does the green text hurt your eyes, or is it nostalgic? 🟩

webdev #react #design #startup

Top comments (0)