DEV Community

Cover image for Missing Rails Console? Building a Database REPL for NestJS + Prisma
Christoph Grothaus
Christoph Grothaus

Posted on

Missing Rails Console? Building a Database REPL for NestJS + Prisma

TL;DR: Coming from Rails/Phoenix, I missed having an interactive database console. So I built one for my NestJS + Prisma stack. Here's how and why.

The Problem: No Interactive Database Console 😒

If you've ever worked with Ruby on Rails or Elixir Phoenix, you know the joy of having an interactive console at your fingertips:

# Rails
rails console
> User.where(active: true).count
=> 1337

# Phoenix
iex -S mix
> MyApp.Repo.all(User)
Enter fullscreen mode Exit fullscreen mode

These REPLs are game-changers for development. Need to quickly test a query? Explore your data model? Debug a complex association? Just fire up the console and start experimenting.

But when I switched to NestJS + Prisma... πŸ€·β€β™‚οΈ

Sure, there's prisma studio for a GUI, but sometimes you just want to code your way through the data. You want to:

  • Quickly prototype complex queries
  • Test edge cases without writing full test files
  • Explore data relationships interactively
  • Debug production data issues with real queries

The Solution: DIY Database Console πŸ› οΈ

So I built my own (of course with a lot AI assistance by Claude Sonnet)! Meet the Prisma DB Console - a Rails-like interactive REPL for Prisma:

#!/usr/bin/env ts-node

import { PrismaClient } from '@prisma/client';
import repl from 'repl';
import util from 'util';

// Initialize Prisma with query logging
const prisma = new PrismaClient({
  log: [
    { emit: 'event', level: 'query' },
    { emit: 'stdout', level: 'error' },
    { emit: 'stdout', level: 'info' },
    { emit: 'stdout', level: 'warn' },
  ],
});

// Log SQL queries with params and timing
prisma.$on('query', (e) => {
  console.log('---');
  console.log(e.query);
  console.log(e.params);
  console.log(String(e.duration) + 'ms');
  console.log('---');
});
Enter fullscreen mode Exit fullscreen mode

Key Features That Make It Awesome ✨

1. Prisma Client Pre-loaded

No more import boilerplate - just start querying:

db-console> await prisma.user.findMany()
db-console> await prisma.organization.count()
Enter fullscreen mode Exit fullscreen mode

2. SQL Query Visibility

See exactly what SQL gets generated, with parameters and execution time:

---
SELECT "User"."id", "User"."email" FROM "User"
[]
12ms
---
Enter fullscreen mode Exit fullscreen mode

3. Helpful Examples on Startup

Because who remembers all the Prisma syntax?

πŸš€ Prisma DB Console
πŸ“Š Prisma Client loaded as "prisma"
πŸ’‘ Examples:
   await prisma.user.findMany()
   await prisma.tenant.count()
   await prisma.$queryRaw`SELECT COUNT(*) FROM "user"`
   await prisma.organization.findFirst({ include: { tenants: true } })
Enter fullscreen mode Exit fullscreen mode

4. Clean Exit Handling

Properly disconnects from the database when you exit:

function cleanupAndExit() {
  console.log('\nπŸ‘‹ Disconnecting from database...');
  prisma.$disconnect()
    .finally(() => process.exit(0));
}
Enter fullscreen mode Exit fullscreen mode

Usage: Simple as npm run db:console πŸš€

Added it as an npm script for easy access:

{
  "scripts": {
    "db:console": "ts-node bin/db-console.ts"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now I can just run:

npm run db:console
# or
pnpm db:console
Enter fullscreen mode Exit fullscreen mode

And I'm off to the races! Perfect for:

  • Data exploration: await prisma.user.findMany({ include: { profile: true } })
  • Quick counts: await prisma.order.count({ where: { status: 'PENDING' } })
  • Complex queries: await prisma.$queryRaw\SELECT * FROM ...``
  • Testing relationships: Verify those Prisma relations work as expected

The Real Impact πŸ“ˆ

Instead of:

  1. Writing a throwaway script
  2. Adding console.logs
  3. Running the script
  4. Deleting the script
  5. Repeat...

I just:

  1. Open console
  2. Experiment
  3. Done!

Want to Build Your Own? πŸ”¨

The full implementation is about 70 lines of TypeScript. Key ingredients:

  • Node's built-in repl module
  • Your Prisma client
  • Event-based query logging
  • Proper cleanup handlers
  • Some helpful utilities in the REPL context

The beauty is in its simplicity - no external dependencies beyond what you already have in a NestJS + Prisma project. The full code of my db-console.ts is available on GitHub Gist if you want to copy and adapt it.

Closing Thoughts πŸ’­

Sometimes the best tools are the ones you build yourself. They fit your exact workflow, solve your specific pain points, and give you that Rails-like developer experience you've been missing.

If you're working with NestJS + Prisma and find yourself constantly writing throwaway scripts to test database queries, consider building your own console. Your future self will thank you!


What is your experience in the NestJS + Prisma ecosystem? Did I miss out on an existing solution? Just drop a comment below!


Top comments (0)