<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yatish Mehta</title>
    <description>The latest articles on DEV Community by Yatish Mehta (@yatish_me).</description>
    <link>https://dev.to/yatish_me</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2823224%2F3657ccca-4458-480c-aa6f-83ef747edcf8.jpeg</url>
      <title>DEV Community: Yatish Mehta</title>
      <link>https://dev.to/yatish_me</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yatish_me"/>
    <language>en</language>
    <item>
      <title>Setting Up a Rails 8 with Vite and Tailwind CSS 4</title>
      <dc:creator>Yatish Mehta</dc:creator>
      <pubDate>Wed, 05 Mar 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/yatish_me/setting-up-a-rails-8-with-vite-and-tailwind-css-4-4na5</link>
      <guid>https://dev.to/yatish_me/setting-up-a-rails-8-with-vite-and-tailwind-css-4-4na5</guid>
      <description>&lt;p&gt;This guide will walk you through setting up a new Ruby on Rails 8 application using Vite(Vite Ruby) as the asset pipeline and Tailwind CSS v4 for styling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fso1e2nokdmrjdbvlfrql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fso1e2nokdmrjdbvlfrql.png" alt="Setup a new app using Rails 8, Vite and Tailwind 4" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a New Rails Project
&lt;/h2&gt;

&lt;p&gt;Since we will be using Vite as our asset pipeline, we will create a new Rails app without JavaScript:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new --skip-javascript my_app_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, add the required gems for Turbo, Stimulus, and Vite in the Gemfile:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails"
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails"
# Vite.js integration in Ruby web apps [https://vite-ruby.netlify.app/]
gem "vite_rails"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create a package.json file using yarn init&lt;/p&gt;

&lt;p&gt;Alternatively, you can manually create package.json with the following content:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "my_app_name",
  "private": "true",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run bundle to install these gems.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Rails 8 uses Propshaft by default, which adds app/assets. Since we are using Vite as our primary asset pipeline, Propshaft can be removed unless needed for other gems like mission control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting Up Vite
&lt;/h2&gt;

&lt;p&gt;Generate Vite configuration files using the vite_rails gem&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec vite install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;vite.config.mts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;config/vite.json&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;app/frontend/ (the home for all frontend-related assets)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app/frontend/entrypoints/ directory contains files acting as entry points for JavaScript and stylesheets. These are referenced in app/views/layouts/application.html.erb using vite_javascript_tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Vite Plugins
&lt;/h2&gt;

&lt;p&gt;Add the Vite Rails plugin and Rollup:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D vite-plugin-rails rollup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Update vite.config.mts to load the plugin:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from "vite";
import ViteRails from "vite-plugin-rails";

export default defineConfig({
  plugins: [
    ViteRails({
      envVars: { RAILS_ENV: "development" },
      envOptions: { defineOn: "import.meta.env" },
      fullReload: {
        additionalPaths: ["config/routes.rb", "app/views/**/*"],
        delay: 300,
      },
    }),
  ],
  build: { sourcemap: false },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Setting Up Turbo &amp;amp; Stimulus
&lt;/h2&gt;

&lt;p&gt;Since we created the app with --skip-javascript, the default app/javascript folder is missing. We need to create it temporarily:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p app/javascript &amp;amp;&amp;amp; touch app/javascript/application.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Install Turbo
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/rails turbo:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Install Stimulus
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/rails stimulus:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, move the javascript folder to app/frontend:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv app/javascript app/frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Update the entry point in app/frontend/entrypoints/application.js:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "../javascript/application";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your file structure should now look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/frontend
├── entrypoints
│   └── application.js
├── javascript
│   ├── application.js
│   └── controllers
│       ├── application.js
│       ├── hello_controller.js
│       └── index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Setting Up Tailwind CSS v4
&lt;/h3&gt;

&lt;p&gt;Tailwind CSS v4 comes with a dedicated Vite plugin. Install it:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add -D tailwindcss @tailwindcss/vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Update vite.config.mts&lt;/p&gt;

&lt;p&gt;Modify vite.config.mts to include the Tailwind plugin:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from "vite";
import ViteRails from "vite-plugin-rails";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [
    tailwindcss(),
    ViteRails({
      envVars: { RAILS_ENV: "development" },
      envOptions: { defineOn: "import.meta.env" },
      fullReload: {
        additionalPaths: ["config/routes.rb", "app/views/**/*"],
        delay: 300,
      },
    }),
  ],
  build: { sourcemap: false },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Add Tailwind to Stylesheets
&lt;/h3&gt;

&lt;p&gt;Create app/frontend/entrypoints/application.css and import Tailwind:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import "../stylesheets/application.tailwind.css";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then, create app/frontend/stylesheets/application.tailwind.css and add:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import "tailwindcss";

@source "../../../app/views/**/*.html.erb";
@source "../../../app/views/**/*.rb";
@source "../../../app/helpers/**/*.rb";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, update application.html.erb to load the stylesheet:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= vite_stylesheet_tag "application.css" %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Final File Structure&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/frontend&lt;br&gt;
├── entrypoints&lt;br&gt;
│   ├── application.css&lt;br&gt;
│   └── application.js&lt;br&gt;
├── javascript&lt;br&gt;
│   ├── application.js&lt;br&gt;
│   └── controllers&lt;br&gt;
│       ├── application.js&lt;br&gt;
│       ├── hello_controller.js&lt;br&gt;
│       └── index.js&lt;br&gt;
└── stylesheets&lt;br&gt;
    └── application.tailwind.css&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Wrapping up&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Now, you have a Rails 8 app set up with Vite and Tailwind CSS v4. 🎉&lt;/p&gt;

&lt;p&gt;If you are looking for a Rails template/SaaS starter based on this stack, check out: &lt;a href="https://github.com/yatish27/shore" rel="noopener noreferrer"&gt;https://github.com/yatish27/shore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>tailwindcss</category>
      <category>vite</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
