Blog

Lee las últimas noticias de la plantilla para aplicaciones SaaS con Remix.

Volver al blog
March 23, 2025

Tailwind CSS v4, Resend, SendGrid, Prisma Multi-File schema, and Dark Mode

  • Nombre
    Alexandro Martínez
    #react-router
    #tailwindcss
    #claude
    #resend
    #sendgrid
    #ai
    #cursor
    #prisma
Tailwind CSS v4, Resend, SendGrid, Prisma Multi-File schema, and Dark Mode

This release includes updates to Tailwind CSS v4, Resend and SendGrid support, Prisma multi-file schema architecture, and introduces Dark Mode support inside /app routes.

Tl;DR:

  • 🤖 AI Rules Directory

  • 🎨 Tailwind CSS v4 Migration

  • 📁 Prisma Multi-file Schema

  • ✉️ New Email Providers: Resend and SendGrid

  • 🌙 Dark Mode at /app

  • 🧹 Code Cleanup

Or watch the 1.6 release video.

🤖 AI Rules Directory

Watch demo here, or browse the directory.

🎨 Tailwind CSS v4 Migration

The most significant change is the upgrade to Tailwind CSS v4. I wrote the following notes after I ran the official Tailwind CSS v4 migration command (npx @tailwindcss/upgrade@next).

globals.css: each utility class separated with @utility {class}

// these keys were automatically migrated with the official CLI: bg-gradient-X → bg-linear-X outline-none → outline-hidden flex-shrink-X → shrink-X flex-grow → grow shadow → shadow-sm shadow-sm → shadow-xs max-w-screen-xl → max-w-(—breakpoint-xl) bg-opacity-X deprecated -> bg-gray-500/75

However, to ensure full compatibility, read the official migration guides:

This now lets you set a mono font and/or scaled, like in the shadcn tailwindcss v4 demo. The previous image uses the font blue-mono from defaultThemes, and themes.css.

✉️ New Email Providers

Added support for more email service providers:

This can be configured in the appConfiguration.db.server.ts file:

// app/utils/db/appConfiguration.db.server.ts
export async function getAppConfiguration(...) {
  const { t } = await getTranslations(request);
  const defaultEmailConfig: AppConfiguration["email"] = {
    provider: "postmark", // postmark, resend, or sendgrid
    fromEmail: "alex@saasrock.com",
    fromName: "Alex @ SaasRock",
    supportEmail: "alex.martinez@absys.com.mx",
  };
  ...

📁 Prisma Multi-file Schema

This significant architecture change requires careful adaptation.

Before:

  • A single schema.prisma file for all database models.

Now:

  • Future-proof schema organization (accounts.prisma, blog.prisma, permissions.prisma, etc.)

  • A dedicated file for your custom models: app.prisma.

Run npx prisma db push after upgrading and carefully verify your database will not be reset.

🌙 Dark Mode at /app

Dark Mode is now supported within the /app routes (not 100%, but it's a start).

Before:

saasrock-before.png

Now (dark mode):

saasrock-dark-mode.png

And light mode:

saasrock-light-mode.png

You can still have a dark sidebar... app/application/Constants.ts:

export const DARK_MODE_IN_APP = true;
export const DARK_SIDEBAR_IN_LIGHT_MODE = false; // set to true
saasrock-light-dark.png

I wrote the following notes when I was adding dark mode support:

// files to exclude: ColorUtils,ColorText,app/utils/shared/colors,HoverEffect
// find and replace:
bg-white → bg-background
bg-gray-50 → bg-secondary
bg-theme-100 -> bg-secondary
text-gray-700 → text-foreground/80
text-gray-[400,500,600] → text-muted-foreground
text-gray-[800,900] → text-foreground
border-gray-[100,200,300,400,500,50] → border-border
divide-gray-[100,200] → divide-border
bg-gray-800 → bg-foreground/90
bg-gray-100 → bg-secondary/90
border-slate-[100,200,300] → border-border
bg-slate-50 → bg-secondary
ring-theme-[500,600] → ring-ring
ring-accent-500 → ring-ring
border-theme-[200,800] -> border-border

Dark Mode inside /app is supported but not 100% tested. To disable Dark Mode in the app, set DARK_MODE_IN_APP to false.

🧹 Code Cleanup

Several unused or deprecated database models and components have been removed:

  • Deleted models: AppCookie, Module, TenantUserRole, Tag, TagUser, TagTenant.

  • Deleted the Tenant Relationships module and db models: TenantTypeEntity, TenantTypeRelationship.

  • Deleted the Linked Accounts module and db models: LinkedAccount.

They existed for a reason, but it's nice to delete unused code.

🛠️ Other Improvements


🚀 Upgrade Instructions

  1. Migrate your custom Prisma models first:

    • The new multi-file schema structure separates models into domain-specific files:

      app.prisma
      accounts.prisma         entityBuilder.prisma    permissions.prisma      analytics.prisma        featureFlags.prisma     portals.prisma
      blog.prisma             helpDesk.prisma
      core.prisma             knowledgeBase.prisma    schema.prisma           email.prisma            onboarding.prisma       subscriptions.prisma                        pageBlocks.prisma       workflows.prisma
    • Move your custom models to the appropriate domain file, with app.prisma (empty by default) recommended for most custom models

    • Ensure relations between models in different files are properly maintained

    • Verify all imports and model references in your code still work correctly (i.e. prisma not complaining missing relationships)

  2. After migrating your models, run npx prisma db push to apply the changes (which should be basically zero changes, but with a new structure).

  3. Verify your database will not be reset. Fortunately, since prisma@6.5.0, you can no longer accidentally push db changes resetting data.

  4. Review all Dark Mode changes if you've customized UI components (If Dark Mode in /app causes issues, set DARK_MODE_IN_APP to false)

  5. For Vercel deployments, go to project settings and change the preset to React Router. I'm not sure why I did not need this, but here's the official Vercel + React Router preset.

If you're having issues with Tailwind CSS v4 support, you could run:

  • npm install tailwindcss@3 (otherwise the next cmd won't work).

  • npx @tailwindcss/upgrade@next.

  • ...and follow shadcn guide


🛒 SaaS Plugins Marketplace (cancelled)

I was exploring the idea for a marketplace for functional SaaS blocks in upcoming releases, allowing you and me to share and monetize reusable components with revenue sharing (see the original idea), BUT then Cursor, Claude, Vibe Coding, and many free shadcn (and premium) blocks exploded, so this idea died, as I can see it would be very difficult to stay up to date against AI-generated code.

saas-plugins.png


What's Next

I'm still not sure, but Let me know your thoughts 😁!

Respetamos tu privacidad.

TLDR: Usamos cookies para la selección de idioma, tema y analíticas. Ver más.