Templatus is an opinionated template to build web applications with Ruby on Rails and Vue.js 3. It simplifies the process of setting up a new application while following best practices.
Live demo available at https://templatus-vue.ledermann.dev
There are two sister repositories:
Using Hotwire instead of Vue.js (the "DHH way"): https://github.com/templatus/templatus-hotwire/
Using Inertia and Svelte.js instead of Vue.js; https://github.com/templatus/templatus-inertia/
- Ruby 3.4
- Ruby on Rails 8.0
- ActionCable for WebSocket communication
- PostgreSQL for using as SQL database
- Sidekiq for background processing
- Redis for Caching, ActionCable, and Sidekiq
- Vite for bundling JavaScript and CSS with Hot Module Replacement (HMR) in development
- Vue 3 as frontend framework
- Vue Router 4 for frontend routing
- Pinia for frontend state management
- Tailwind CSS 3 to not have to write CSS at all
- Heroicons for SVG icons as Vue components
- Rails Request.JS for AJAX requests with default headers
- Puma-dev for using
.test
TLD (instead oflocalhost:3000
) andhttps
in development - Overmind for starting up the application locally (Procfile handling like Foreman)
- dotenv to load environment variables from .env into ENV
- TypeScript for writing strongly-typed JavaScript
- Prettier for auto-formatting TypeScript and Ruby code in Visual Studio Code
- annotate for annotating models and routes
- RuboCop for Ruby static code analysis
- RSpec for Ruby testing
- ESLint for TypeScript static code analysis
- Jest for TypeScript unit testing
- Cypress for E2E testing
- Docker for production deployment, NOT for development
- DockerRailsBase for fast building an optimized Docker image based on Alpine Linux
- GitHub Actions for testing, linting, and building Docker image
- Dependabot configuration for updating dependencies (with auto-merge)
- Ready for serving assets via CDN like CloudFront
- Honeybadger for error tracking in Ruby and TypeScript
- RorVsWild for performance monitoring
- Plausible for privacy friendly analytics
- Lograge for single-line logging
- Gzip compression of dynamic responses (HTML, JSON) using Rack::Deflater
- Fine-tuned Content Security Policy (CSP)
- Ready for PWA (manifest, service-worker)
This template is developed with optimized performance and security in mind. The following benchmarks are performed against the demo installation on production. It uses an inexpensive virtual server on the Hetzner Cloud behind a Traefik setup.
100% in all categories.
What's the red Permissions-Policy badge? This seems to be fixed with one of the next Rails update: rails/rails#41994
154 KB of compiled JavaScript (after tree-shaking, minified & uncompressed). The largest parts are:
- Vue.js + Vue Router (75 KB)
- Honeybadger (23 KB)
- ActionCable (9 KB)
- Pinia (6 KB)
$ RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 bin/rails assets:precompile
Building with Vite ⚡️
vite v5.4.3 building for production...
transforming...
✓ 729 modules transformed.
rendering chunks...
computing gzip size...
../../public/vite/.vite/manifest-assets.json 0.10 kB │ gzip: 0.09 kB
../../public/vite/assets/logo-DIorPG93.svg 0.50 kB │ gzip: 0.30 kB
../../public/vite/.vite/manifest.json 0.64 kB │ gzip: 0.24 kB
../../public/vite/assets/application-BzEOTfLU.css 23.65 kB │ gzip: 5.18 kB
../../public/vite/assets/application-CI1loYrW.js 18.12 kB │ gzip: 7.19 kB │ map: 31.58 kB
../../public/vite/assets/vendor-C8Gi253Q.js 168.57 kB │ gzip: 60.16 kB │ map: 1,103.22 kB
✓ built in 1.33s
Build with Vite complete: /Users/ledermann/Projects/templatus-vue/public/vite
Small footprint: The demo application transfers only 69 KB of data on the first visit.
With multi-stage building and using DockerRailsBase the build of the Docker image takes very little time. Currently, the build job requires about 1,5 minutes on GitHub Actions (see https://github.com/templatus/templatus-vue/actions)
The Docker image is based on Alpine Linux and is optimized for minimal size (currently 113 MB uncompressed disk size). It includes just the bare minimum - no build tools like Node.js, no JS sources (just the compiled assets), no tests.
$ container-diff analyze ghcr.io/templatus/templatus-vue -n
-----Size-----
Analysis for ghcr.io/templatus/templatus-vue:
IMAGE DIGEST SIZE
ghcr.io/templatus/templatus-vue sha256:... 114.8M
- Clone the repo locally:
git clone [email protected]:templatus/templatus-vue.git
cd templatus-vue
- Install PostgreSQL, Redis, and puma-dev (if not already present). On a Mac with Homebrew, run this to install from the
Brewfile
:
brew bundle
- Set up puma-dev to use HTTPS for development. Do this on macOS:
sudo puma-dev -setup
puma-dev -install
puma-dev link
# Use Vite via puma-dev proxy
# Adopted from https://github.com/puma/puma-dev#webpack-dev-server
echo 3036 > ~/.puma-dev/vite.templatus-vue
- Setup the application to install gems and NPM packages and create the database:
bin/setup
- Start the application locally:
bin/dev
Then open https://templatus-vue.test in your browser.
RuboCop:
bin/rubocop
ESLint:
bin/yarn lint
TypeScript compiler:
bin/yarn tsc
Ruby tests:
bin/rspec
open coverage/index.html
JavaScript unit tests:
bin/yarn test
E2E tests with Cypress:
bin/cypress open
This opens Cypress and starts Rails in development
environment, but with CYPRESS=true
, so the test
database is used. This allows code editing without class reloading and recompiling assets.
To run Cypress in headless mode:
bin/cypress run
docker network create public
docker-compose up