January 2026 Update: Still Going Strong with Jekyll
I’m Still Using Jekyll
Happy New Year 2026! Since migrating from Tumblr to Jekyll (and GitHub Pages) back in 2014, I have remained loyal to the same stack, now with the addition of @divriots/jampack at the end of the build chain.
Truthfully, I have tried many other SSGs: Hugo, Gatsby, Hexo, VuePress (or VitePress, I can’t recall which), Eleventy, Zola, Metalsmith, Lume, bashblog, and probably many others listed on Jamstack. At the end of the day, I always find myself thinking, “Jekyll just feels more comfortable.”
I can’t say Jekyll is perfect. Even now, my desire to have anchor headings remains unfulfilled. This issue has been open for over a year. I’m still conflicted about the implementation: should I use a Jekyll plugin, Node.js-based JavaScript, or just browser-side JavaScript? (To be honest, I hate the latter approach because I disable JavaScript on all my browsers).
When looking at other SSGs, implementing anchor headings seems so easy. Add a plugin, configure it, build, and voilà—anchor headings are done.
Initially, build optimization was also a struggle. There was jekyll-assets, which hashed every CSS, JS, and image file. This was great for ensuring that rapidly changing files wouldn’t clash with browser caches. In other SSGs, this feature is often built-in, especially in JavaScript-based ones like Eleventy, Gatsby, or Hexo.
Then there’s the issue of managing image files served to the end-user. Jekyll lacks a built-in feature for this, unlike other modern SSGs. With the advent of srcset, the <picture> element, WebP, and AVIF, I found myself wondering, “How can I get these features on my blog?”
Furthermore, there is the question of how to load CSS into HTML. The most aggressive way is to inline everything in the <head><style>...</style></head>. But when I tried this while using the Minimal Mistakes theme, the CSS actually outweighed the HTML markup. I also tried loading via JS using this.onload, but the FOUC (Flash of Unstyled Content) was far too obvious. ![]()
The point is, I am someone who deeply values optimization, security, and privacy. A site should load fast, stay secure using current standards, and respect privacy—these are amazing things to prioritize.
After that long journey, I finally found @divriots/jampack.
Jampack is My Savior
Jampack serves one primary purpose: optimizing the files already built by an SSG. It handles inlining above-the-fold CSS, deferring JS files, generating hashed image names, creating WebP and AVIF versions (though AVIF can slow down build times), adding loading=lazy, and much more. You should check out their documentation.
For some reason, I feel Jampack doesn’t get the spotlight it deserves. Reducing the optimization hurdles inherent in many SSGs is a huge win.
I don’t use every single Jampack feature. My configuration is quite simple, leaving the rest to the defaults:
// jampack.config.mjs
const default_options = {
html: {
sort_attributes: true,
},
image: {
external: {
process: 'download',
},
},
cdn: {
process: 'on',
},
};
export default default_options;
With just that config, my Lighthouse scores can hit 90+. I know you shouldn’t measure performance by Lighthouse scores alone, but it gives a good overview of the improvements gained just by adding Jampack.
Integrating Jampack does require additional setup if you aren’t using a Node.js-based SSG. Fortunately, Cloudflare Pages support both Ruby and nodejs, offers non-production build previews and 500 builds per month, which is more than enough for personal use. I can just use Github from a browser, write by myself or ask AI to generate code I want, test it on another branch, Cloudflare Pages build a preview of it, repeat.
Additionally, with the help of AI like Claude, Amazon Q Developer, Copilot, and Gemini, I can develop easily even from my phone (getting Jekyll to work in Termux is still hard to this day). Just remember: always check the code generated by AI. Not all of it is good; they can hallucinate, and their knowledge cut-offs mean they aren’t always up to date. So, always cross-check.
AI is great, provided you use it correctly.
To wrap things up, here is the changelog for the updates I’ve been working on gradually from December through mid-January, generated by Amazon Q. ![]()
January 2026 update changelog
Changelog
🎨 Theme Migration
- Migrated from apropixyll to minima: Switched to Jekyll’s official minima theme for better maintainability
- New homepage design: Created a custom profile landing page with clean button-style navigation links
- Responsive styling: Implemented theme-aware CSS using minima’s native CSS variables for automatic dark/light mode support
🌐 Infrastructure Changes
- Hosting migration: Moved from GitHub Pages to Cloudflare Pages (<akhyar.id> domain)
- Enhanced security: Added comprehensive security headers including HSTS and frame protection
- Optimized caching: Implemented intelligent caching policies for static assets vs dynamic content
- Service Worker improvements: Enhanced offline functionality with better error handling and cache management
🔧 Configuration Updates
- Streamlined dependencies: Removed unused plugins (jekyll-paginate, jekyll-github-metadata, jekyll-redirect-from)
- Updated site metadata: Refreshed author information, social links, and SEO configuration
- Modernized contact form: Rebuilt contact page with improved styling and AJAX submission via Formspree
📝 Content & Localization
- Language migration: Translated primary content from Indonesian to English (some stuff still in Indonesian tho)
- Updated navigation: Restructured site navigation with profile, contact, and privacy policy pages
- Enhanced 404 page: Created custom styled 404 page matching the new theme
- Redirect management: Implemented Jekyll-generated redirects for legacy URLs
🗂️ File Structure Changes
- Removed legacy files: Cleaned up old theme files, JSONP endpoints, and unused configurations
- Added new components: Custom header, favicon management, and theme customizations
- Updated assets: New favicon set and web manifest for PWA support
This migration represents a complete modernization of the site architecture while maintaining content accessibility and improving user experience across devices and themes.
Thanks for reading. Bye~