Howdy Jekyll Theme
A clean, modern, and minimalist Jekyll theme for personal websites and portfolios.
Live Demo · Installation · Configuration · Contributing
Requirements
| Dependency | Version | Required |
|---|---|---|
| Ruby | >= 3.0 | Yes |
| Jekyll | >= 3.9 | Yes |
| Bundler | >= 2.4 | Yes |
| Node.js | >= 18 | For Lighthouse CI only |
Screenshots
| Light Mode | Dark Mode |
|---|---|
![]() |
![]() |
Features
| Feature | Description |
|---|---|
| Gem-based | Easy installation via RubyGems |
| Light & Dark | Toggle with persistent preference, respects system preference |
| Responsive | Desktop, tablet, and mobile optimized |
| Hero Carousel | Touch/swipe-enabled, Swiper.js powered, fade transitions, autoplay |
| Projects | Portfolio collection sorted by year with dedicated layouts |
| Blog | jekyll-paginate-v2 powered with category color accents |
| SEO | jekyll-seo-tag integration |
| RSS | Automatic feed via jekyll-feed |
| TOC | Auto-generated table of contents with configurable heading levels |
| Share | Twitter, LinkedIn, Facebook, Reddit, Hacker News, WhatsApp, Telegram, Email, and copy-link buttons |
| Newsletter | Mailchimp, Buttondown, or custom form support |
| Comments | Giscus, Disqus, or Utterances |
| Analytics | Google Analytics or Plausible |
| Company Logos | Configurable "Trusted by" marquee section |
| Fonts | Local DM Sans variable font + Chaumont Script logo font. Configurable via fonts.primary and fonts.mono |
Browser Compatibility
| Browser | Version | Supported |
|---|---|---|
| Chrome | 120+ | ✅ |
| Firefox | 115+ | ✅ |
| Safari | 16+ | ✅ |
| Edge | 120+ | ✅ |
Known Quirks
- Firefox scrollbars: Uses
scrollbar-colorandscrollbar-width(native thin scrollbars).::-webkit-scrollbarrules are ignored. - Safari
scroll-margin-top: Fully supported in Safari 15+. Older versions may requirepadding-topworkaround on headings. - Safari SVG
loading="lazy": SVG images do not support lazy loading in Safari; they load eagerly regardless of attribute.
Automated Testing
This theme includes Playwright end-to-end tests covering:
| Test Suite | Coverage |
|---|---|
nav.spec.js |
Hamburger toggle, ESC/overlay close, desktop hide |
theme.spec.js |
Light/dark toggle, localStorage persistence, reload restore |
carousel.spec.js |
Dot navigation, swipe gestures, slide dimensions |
toc.spec.js |
Anchor scroll, scroll-margin offset, TOC presence |
transitions.spec.js |
Page fade-out, external/hash link exclusion |
npm test # Run all tests
npm run test:ui # Interactive UI mode
Installation
New Jekyll Site
jekyll new my-site --skip-bundle
cd my-site
Add the Theme
Add to your Gemfile:
gem "howdy-jekyll-theme"
Add to your _config.yml:
theme: howdy-jekyll-theme
Then install:
bundle config --local path .bundle
bundle install
Troubleshooting: If you run into permission issues or conflicts with system gems, run
bundle config --local path .bundlebeforebundle install. This vendors all gems into the project's.bundle/directory, keeping your environment isolated.
Existing Site
Remove any theme: and remote_theme: lines from _config.yml, delete _layouts, _includes, and _sass directories, then follow the steps above.
Configuration
Minimal Setup
# _config.yml
title: "Your Name"
description: "Your site description"
author: "Your Name"
email: "hi@yoursite.com"
url: "https://yoursite.com"
baseurl: ""
theme: howdy-jekyll-theme
plugins:
- jekyll-seo-tag
- jekyll-feed
- jekyll-sitemap
- jekyll-paginate-v2
collections:
projects:
output: true
permalink: /projects/:slug/
sort_by: year
pagination:
enabled: true
per_page: 5
permalink: "/blog/page:num/"
sort_reverse: true
Hero Carousel
Single image or multi-image carousel:
# Single image
hero_image: /assets/images/hero.png
# Carousel (2+ images enables touch/swipe)
hero_images:
- /assets/images/hero-1.jpg
- /assets/images/hero-2.jpg
- /assets/images/hero-3.jpg
Navigation
navigation:
- title: "Home"
url: "/"
- title: "Projects"
url: "/projects/"
- title: "Blog"
url: "/blog/"
- title: "About"
url: "/about"
Social Links
social:
github: "https://github.com/yourusername"
twitter: "https://x.com/yourusername"
linkedin: "https://linkedin.com/in/yourusername"
instagram: "https://instagram.com/yourusername"
dribbble: "https://dribbble.com/yourusername"
Homepage Hero
hero:
headline: "I shape product strategy<br>& design experiences<br><span class=\"text-muted\">at scale</span>"
subtitle: "Your tagline or short description."
cta_text: "View case studies"
cta_url: "/projects/"
About Page
about_bio: "Your intro paragraph. <strong>HTML</strong> supported."
about_headline: "Building products that<br>sit at the intersection<br><span class=\"text-muted\">of design and intelligence</span>"
about_paragraph_2: "Your second paragraph."
about_paragraph_3: "Your third paragraph."
about_hero_image: "/assets/illustrations/designer.svg"
about_resume:
enabled: true
text: "Download Resume"
url: "/assets/resume.pdf"
# Testimonials (shown on about page)
testimonials:
- quote: "A great testimonial quote."
name: "Jane Doe"
role: "Title, Company"
Pagination
pagination:
enabled: true
per_page: 5
permalink: "page:num/"
sort_reverse: true
prev_text: "Prev"
next_text: "Next"
404 Page
page_404:
title: "Page Not Found"
message: "The page you're looking for doesn't exist or has been moved."
button_text: "Go Home"
button_url: "/"
Fonts
fonts:
primary: "DM Sans" # DM Sans, Inter, Plus Jakarta Sans, Instrument Sans, Space Grotesk, Work Sans, Outfit, Manrope, Sora
mono: "Fragment Mono" # Fragment Mono, JetBrains Mono, Fira Code
Company Logos Marquee
company_logos:
enabled: true
items:
- name: "Company 1"
width: 120
url: "https://company1.com"
- name: "Company 2"
width: 100
url: "https://company2.com"
Newsletter, Comments, Analytics
# Newsletter
newsletter:
enabled: true
provider: buttondown # mailchimp, buttondown, custom
action_url: "https://..." # form action URL
title: "Stay updated"
# Comments
comments:
enabled: false
provider: giscus # giscus, disqus, utterances
giscus:
repo: "user/repo"
repo_id: "R_XXXXXXXX"
category: "Announcements"
category_id: "DIC_XXXXXXXX"
# Analytics
analytics:
provider: plausible # google, plausible
plausible_domain: "yoursite.com"
Content Types
Projects
Create files in _projects/:
---
layout: project
title: "Project Name"
subtitle: "Brief description"
category: "Web Design"
year: "2025"
image: /assets/images/project.jpg
---
Project content with markdown...
Blog Posts
Create files in _posts/ with naming format YYYY-MM-DD-slug.md:
---
layout: post
title: "Post Title"
category: "Tutorials" # Tutorials, Inspiration, Freebies, Interviews
image: /assets/images/post.jpg
---
Post content...
Tip: Use
<!--more-->to define the excerpt shown on the blog index.
Customization
Override Styles
Create assets/css/main.scss in your site:
---
---
@use "variables";
@use "base";
@use "typography";
@use "layout";
@use "components";
@use "dark-mode";
// Your styles here
Override Partials
Copy any _includes/ or _layouts/ file into your site's directory with the same path. Jekyll will use your version instead of the theme's.
User Color Palette
Override the green accent in your _config.yml:
colors:
accent_green: "#008a1e"
Development
git clone https://github.com/howdyitskyle/howdy-jekyll-theme.git
cd howdy-jekyll-theme
bundle config --local path .bundle
bundle install
bundle exec jekyll serve
Visit http://localhost:4000.
Testing
bundle exec rake test # HTML validation (links, images, scripts)
bundle exec rake validate_config # Config field checks
bundle exec rake lighthouse # Performance & accessibility audits
bundle exec rake all # All of the above
Lighthouse CI asserts accessibility >= 0.9 across 5 pages.
Build the Gem
gem build howdy-jekyll-theme.gemspec
gem install ./howdy-jekyll-theme-1.0.0.gem
File Structure
├── _includes/ # 12 partials (nav, hero-carousel, toc, share, etc.)
├── _layouts/ # 7 layouts (default, home, page, post, project, blog, collection)
├── _sass/ # 7 stylesheets (variables, base, typography, layout, components, dark-mode, user-colors)
├── assets/
│ ├── css/ # main.scss, swiper-bundle.min.css
│ ├── js/ # hero-carousel.js, mobile-nav.js, theme-toggle.js, swiper-bundle.min.js
│ ├── fonts/ # ChaumontScript-Regular.otf, DMSans-Variable.ttf, DMSans-Italic-Variable.ttf
│ ├── images/
│ └── illustrations/
├── _projects/ # Demo portfolio items
├── _posts/ # Demo blog posts
├── blog/ # Blog index with pagination
├── lib/ # Gem entry point
├── _config.yml # Fully documented configuration
├── Rakefile # Test runner
└── lighthouserc.json # Lighthouse CI assertions
Contributing
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Bug reports and feature requests are welcome at Issues.
License
This theme is available under the MIT License.
Acknowledgments
- axeltmpl — Design inspired by and remixed from this Framer template
- Illustration Kit — Free SVG illustrations by Pencil
- Swiper.js — Touch-enabled carousel (MIT)
- Chaumont Script — by Måns Grebäck
- Jekyll — Static site generator

