Migrating from Fresh

On this page

Migrating from Deno-based Fresh to Rustyll? This guide will help you transition from Fresh’s real-time rendering approach to Rustyll’s high-performance static site generation while preserving your content and components.

Installation

First, install Rustyll using Cargo (Rust’s package manager):

# Install Rust if you haven't already
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install Rustyll
cargo install rustyll

Automatic Migration

Rustyll provides a built-in migration tool for Fresh sites:

rustyll migrate --from fresh --source ./my-fresh-site --destination ./my-rustyll-site

This command will:

  1. Convert Fresh’s TypeScript/JSX components to static HTML with Liquid templates
  2. Transform Fresh routes to Rustyll pages
  3. Convert islands to static HTML with optional JavaScript enhancement
  4. Generate a migration report

Conceptual Differences

Fresh Rustyll
Deno runtime Rust-based static site generator
Server-side rendering Build-time generation
Islands architecture Static HTML with optional JS
TypeScript/JSX Liquid templates and Markdown
File-system routing File-based pages with front matter

Directory Structure Conversion

Fresh Rustyll Notes
routes/ Root directory Routes become pages
islands/ _includes/ and assets/js/ Interactive components
components/ _includes/ Reusable components
static/ assets/ Static files
main.ts _config.yml Configuration
fresh.gen.ts N/A Not needed in Rustyll
deno.json N/A Not needed in Rustyll

Route Conversion

Fresh routes convert to Rustyll pages:

// Fresh (routes/about.tsx)
import { Head } from "$fresh/runtime.ts";
import Navigation from "../components/Navigation.tsx";

export default function AboutPage() {
  return (
    <>
      <Head>
        <title>About | My Website</title>
        <meta name="description" content="About my website" />
      </Head>
      <div class="page">
        <Navigation active="about" />
        <main>
          <h1>About</h1>
          <p>This is the about page.</p>
        </main>
      </div>
    </>
  );
}

Converts to:

<!-- Rustyll (about.md) -->
---
layout: default
title: About | My Website
description: About my website
---

<div class="page">
  `{% include navigation.html active="about" %}`
  <main>
    <h1>About</h1>
    <p>This is the about page.</p>
  </main>
</div>

Component Conversion

Fresh components convert to Rustyll includes:

// Fresh (components/Navigation.tsx)
interface NavigationProps {
  active: string;
}

export default function Navigation({ active }: NavigationProps) {
  return (
    <nav class="navigation">
      <a href="/" class={active === "home" ? "active" : ""}>Home</a>
      <a href="/about" class={active === "about" ? "active" : ""}>About</a>
      <a href="/blog" class={active === "blog" ? "active" : ""}>Blog</a>
    </nav>
  );
}

Converts to:

<!-- Rustyll (_includes/navigation.html) -->
<nav class="navigation">
  <a href="/" class="{% if include.active == 'home' %}active{% endif %}">Home</a>
  <a href="/about" class="{% if include.active == 'about' %}active{% endif %}">About</a>
  <a href="/blog" class="{% if include.active == 'blog' %}active{% endif %}">Blog</a>
</nav>

Island Conversion

Fresh islands (interactive components) convert to static HTML with optional JavaScript:

// Fresh (islands/Counter.tsx)
import { useState } from "preact/hooks";

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div class="counter">
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Converts to:

<!-- Rustyll (_includes/counter.html) -->
<div class="counter" data-component="counter">
  <p>Count: <span data-counter-value>0</span></p>
  <button data-counter-increment>Increment</button>
</div>

With an accompanying JavaScript file:

// Rustyll (assets/js/counter.js)
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('[data-component="counter"]').forEach(counter => {
    const valueEl = counter.querySelector('[data-counter-value]');
    const button = counter.querySelector('[data-counter-increment]');
    let count = 0;
    
    button.addEventListener('click', () => {
      count += 1;
      valueEl.textContent = count;
    });
  });
});

Data Fetching

Fresh’s server functions convert to static data in Rustyll:

// Fresh (routes/api/data.ts)
export const handler = async (_req: Request): Promise<Response> => {
  const data = await fetchSomeData();
  return new Response(JSON.stringify(data));
};

// Fresh (routes/dashboard.tsx)
import { useEffect, useState } from "preact/hooks";

export default function Dashboard() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch("/api/data").then(res => res.json()).then(setData);
  }, []);
  
  return (
    <div>
      {data ? <pre>null</pre> : <p>Loading...</p>}
    </div>
  );
}

Converts to:

# Rustyll (_data/api_data.yml)
- name: Item 1
  value: 100
- name: Item 2
  value: 200
<!-- Rustyll (dashboard.html) -->
---
layout: default
title: Dashboard
---

<div>
  <pre>null</pre>
</div>

Dynamic Routes

Fresh’s dynamic routes convert to collections in Rustyll:

// Fresh (routes/blog/[slug].tsx)
import { Handlers, PageProps } from "$fresh/server.ts";

export const handler: Handlers = {
  async GET(req, ctx) {
    const { slug } = ctx.params;
    const post = await getPost(slug);
    return ctx.render({ post });
  },
};

export default function BlogPost({ data }: PageProps) {
  const { post } = data;
  return (
    <div>
      <h1></h1>
      <div>{{ content }}</div>
    </div>
  );
}

Converts to:

# Rustyll (_config.yml)
collections:
  posts:
    output: true
    permalink: /blog/:slug/
<!-- Rustyll (_posts/2023-01-15-example-post.md) -->
---
layout: post
title: Example Post
---

This is an example blog post content.
<!-- Rustyll (_layouts/post.html) -->
---
layout: default
---

<div>
  <h1>Migrating from Fresh</h1>
  <div><section class="docs-shell container"><div class="docs-mobile-nav"><details class="mobile-docs"><summary>Browse documentation <span aria-hidden="true">⌄</span></summary><div class="mobile-docs-content"><nav class="docs-links" aria-label="Documentation sections"><h2>Getting Started</h2><ul><li><a href="/docs/" >Quickstart</a></li><li><a href="/docs/installation/" >Installation</a></li><li><a href="/docs/rust-101/" >Rust 101 for Rustyll Users</a></li><li><a href="/docs/community/" >Community</a></li><li><a href="/docs/step-by-step/01-setup/" >Step by Step Tutorial</a></li></ul><h2>Build</h2><ul><li><a href="/docs/usage/" >Command Line Usage</a></li><li><a href="/docs/configuration/" >Configuration</a></li><li><a href="/docs/rendering-process/" >Rendering Process</a></li></ul><h2>Content</h2><ul><li><a href="/docs/pages/" >Pages</a></li><li><a href="/docs/posts/" >Posts</a></li><li><a href="/docs/front-matter/" >Front Matter</a></li><li><a href="/docs/collections/" >Collections</a></li><li><a href="/docs/datafiles/" >Data Files</a></li><li><a href="/docs/assets/" >Assets</a></li><li><a href="/docs/static-files/" >Static Files</a></li></ul><h2>Site Structure</h2><ul><li><a href="/docs/structure/" >Directory Structure</a></li><li><a href="/docs/liquid/" >Liquid</a></li><li><a href="/docs/variables/" >Variables</a></li><li><a href="/docs/includes/" >Includes</a></li><li><a href="/docs/layouts/" >Layouts</a></li><li><a href="/docs/permalinks/" >Permalinks</a></li><li><a href="/docs/themes/" >Themes</a></li><li><a href="/docs/pagination/" >Pagination</a></li></ul><h2>Guides</h2><ul><li><a href="/docs/plugins/" >Plugins</a></li><li><a href="/docs/migrations/" >Blog Migrations</a></li><li><a href="/docs/upgrading/" >Upgrading</a></li><li><a href="/docs/deployment/" >Deployment</a></li></ul><h2>Migrating</h2><ul><li><a href="/docs/migrating/" >Migrating to Rustyll</a></li><li><a href="/docs/migrating/assemble-to-rustyll/" >Migrating from Assemble</a></li><li><a href="/docs/migrating/bridgetown-to-rustyll/" >Migrating from Bridgetown</a></li><li><a href="/docs/migrating/cobalt-to-rustyll/" >Migrating from Cobalt</a></li><li><a href="/docs/migrating/docsy-to-rustyll/" >Migrating from Docsy</a></li><li><a href="/docs/migrating/eleventy-to-rustyll/" aria-current="page">Migrating from Eleventy</a></li><li><a href="/docs/migrating/fresh-to-rustyll/" >Migrating from Fresh</a></li><li><a href="/docs/migrating/gatsby-to-rustyll/" >Migrating from Gatsby</a></li><li><a href="/docs/migrating/gitbook-to-rustyll/" >Migrating from GitBook</a></li><li><a href="/docs/migrating/harp-to-rustyll/" >Migrating from Harp</a></li><li><a href="/docs/migrating/hugo-to-rustyll/" >Migrating from Hugo</a></li><li><a href="/docs/migrating/jekyll-to-rustyll/" >Migrating from Jekyll</a></li><li><a href="/docs/migrating/mdbook-to-rustyll/" >Migrating from mdBook</a></li><li><a href="/docs/migrating/middleman-to-rustyll/" >Migrating from Middleman</a></li><li><a href="/docs/migrating/mkdocs-to-rustyll/" >Migrating from MkDocs</a></li><li><a href="/docs/migrating/nanoc-to-rustyll/" >Migrating from Nanoc</a></li><li><a href="/docs/migrating/pelican-to-rustyll/" >Migrating from Pelican</a></li><li><a href="/docs/migrating/slate-to-rustyll/" >Migrating from Slate</a></li><li><a href="/docs/migrating/zola-to-rustyll/" >Migrating from Zola</a></li></ul></nav>
</div></details>
</div><div class="docs-grid"><aside class="docs-sidebar"><div class="docs-sidebar-inner"><a class="search-trigger" href="/search/" data-search-open>Search documentation <span aria-hidden="true">⌕</span></a><nav class="docs-links" aria-label="Documentation sections"><h2>Getting Started</h2><ul><li><a href="/docs/" >Quickstart</a></li><li><a href="/docs/installation/" >Installation</a></li><li><a href="/docs/rust-101/" >Rust 101 for Rustyll Users</a></li><li><a href="/docs/community/" >Community</a></li><li><a href="/docs/step-by-step/01-setup/" >Step by Step Tutorial</a></li></ul><h2>Build</h2><ul><li><a href="/docs/usage/" >Command Line Usage</a></li><li><a href="/docs/configuration/" >Configuration</a></li><li><a href="/docs/rendering-process/" >Rendering Process</a></li></ul><h2>Content</h2><ul><li><a href="/docs/pages/" >Pages</a></li><li><a href="/docs/posts/" >Posts</a></li><li><a href="/docs/front-matter/" >Front Matter</a></li><li><a href="/docs/collections/" >Collections</a></li><li><a href="/docs/datafiles/" >Data Files</a></li><li><a href="/docs/assets/" >Assets</a></li><li><a href="/docs/static-files/" >Static Files</a></li></ul><h2>Site Structure</h2><ul><li><a href="/docs/structure/" >Directory Structure</a></li><li><a href="/docs/liquid/" >Liquid</a></li><li><a href="/docs/variables/" >Variables</a></li><li><a href="/docs/includes/" >Includes</a></li><li><a href="/docs/layouts/" >Layouts</a></li><li><a href="/docs/permalinks/" >Permalinks</a></li><li><a href="/docs/themes/" >Themes</a></li><li><a href="/docs/pagination/" >Pagination</a></li></ul><h2>Guides</h2><ul><li><a href="/docs/plugins/" >Plugins</a></li><li><a href="/docs/migrations/" >Blog Migrations</a></li><li><a href="/docs/upgrading/" >Upgrading</a></li><li><a href="/docs/deployment/" >Deployment</a></li></ul><h2>Migrating</h2><ul><li><a href="/docs/migrating/" >Migrating to Rustyll</a></li><li><a href="/docs/migrating/assemble-to-rustyll/" >Migrating from Assemble</a></li><li><a href="/docs/migrating/bridgetown-to-rustyll/" >Migrating from Bridgetown</a></li><li><a href="/docs/migrating/cobalt-to-rustyll/" >Migrating from Cobalt</a></li><li><a href="/docs/migrating/docsy-to-rustyll/" >Migrating from Docsy</a></li><li><a href="/docs/migrating/eleventy-to-rustyll/" aria-current="page">Migrating from Eleventy</a></li><li><a href="/docs/migrating/fresh-to-rustyll/" >Migrating from Fresh</a></li><li><a href="/docs/migrating/gatsby-to-rustyll/" >Migrating from Gatsby</a></li><li><a href="/docs/migrating/gitbook-to-rustyll/" >Migrating from GitBook</a></li><li><a href="/docs/migrating/harp-to-rustyll/" >Migrating from Harp</a></li><li><a href="/docs/migrating/hugo-to-rustyll/" >Migrating from Hugo</a></li><li><a href="/docs/migrating/jekyll-to-rustyll/" >Migrating from Jekyll</a></li><li><a href="/docs/migrating/mdbook-to-rustyll/" >Migrating from mdBook</a></li><li><a href="/docs/migrating/middleman-to-rustyll/" >Migrating from Middleman</a></li><li><a href="/docs/migrating/mkdocs-to-rustyll/" >Migrating from MkDocs</a></li><li><a href="/docs/migrating/nanoc-to-rustyll/" >Migrating from Nanoc</a></li><li><a href="/docs/migrating/pelican-to-rustyll/" >Migrating from Pelican</a></li><li><a href="/docs/migrating/slate-to-rustyll/" >Migrating from Slate</a></li><li><a href="/docs/migrating/zola-to-rustyll/" >Migrating from Zola</a></li></ul></nav>
</div>
</aside><div class="docs-main"><div class="doc-content"><nav class="breadcrumbs" aria-label="Breadcrumb"><a href="/docs/">Documentation</a><span aria-hidden="true">/</span><span>Migrating from Eleventy</span></nav><h1>Migrating from Eleventy</h1><details class="mobile-page-toc"><summary>On this page</summary>

<nav class="page-toc " aria-label="On this page"><h2>On this page</h2><ul>

<li class="toc-level-2"><a href="#installation">Installation</a></li><li class="toc-level-2"><a href="#automatic-migration">Automatic Migration</a></li><li class="toc-level-2"><a href="#directory-structure-differences">Directory Structure Differences</a></li><li class="toc-level-2"><a href="#template-differences">Template Differences</a><ul><li class="toc-level-3"><a href="#liquid-templates">Liquid Templates</a></li><li class="toc-level-3"><a href="#nunjucks-to-liquid-conversion">Nunjucks to Liquid Conversion</a></li></ul></li><li class="toc-level-2"><a href="#front-matter">Front Matter</a></li><li class="toc-level-2"><a href="#collections-and-data">Collections and Data</a></li><li class="toc-level-2"><a href="#configuration-conversion">Configuration Conversion</a></li><li class="toc-level-2"><a href="#filters-and-shortcodes">Filters and Shortcodes</a></li><li class="toc-level-2"><a href="#performance-optimization">Performance Optimization</a></li><li class="toc-level-2"><a href="#troubleshooting-common-issues">Troubleshooting Common Issues</a><ul><li class="toc-level-3"><a href="#javascript-templates-and-functions">JavaScript Templates and Functions</a></li><li class="toc-level-3"><a href="#pagination-differences">Pagination Differences</a></li></ul></li><li class="toc-level-2"><a href="#migration-checklist">Migration Checklist</a></li><li class="toc-level-2"><a href="#need-help">Need Help?</a></li>
</ul></nav>
</details><article class="prose prose-invert max-w-none"><p>Migrating from Eleventy (11ty) to Rustyll? This guide will help you transition from JavaScript-based Eleventy to Rust-powered Rustyll while preserving your content and layouts.</p>

<h2 id="installation">Installation</h2>

<p>First, install Rustyll using Cargo (Rust’s package manager):</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install Rust if you haven't already</span>
curl <span class="nt">--proto</span> <span class="s1">'=https'</span> <span class="nt">--tlsv1</span>.2 <span class="nt">-sSf</span> https://sh.rustup.rs | sh

<span class="c"># Install Rustyll</span>
cargo <span class="nb">install </span>rustyll
</code></pre></div></div>

<h2 id="automatic-migration">Automatic Migration</h2>

<p>Rustyll provides a built-in migration tool for Eleventy sites:</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rustyll migrate <span class="nt">--from</span> eleventy <span class="nt">--source</span> ./my-eleventy-site <span class="nt">--destination</span> ./my-rustyll-site
</code></pre></div></div>

<p>This command will:</p>
<ol>
  <li>Copy all content files</li>
  <li>Convert Eleventy-specific front matter to Rustyll format</li>
  <li>Transform templates to Liquid format (if they aren’t already)</li>
  <li>Adjust configuration settings</li>
  <li>Generate a migration report</li>
</ol>

<h2 id="directory-structure-differences">Directory Structure Differences</h2>

<table>
  <thead>
    <tr>
      <th>Eleventy</th>
      <th>Rustyll</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Input directory (configurable)</td>
      <td>Root directory</td>
      <td>Content goes in the root folder in Rustyll</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">_includes/</code></td>
      <td><code class="language-plaintext highlighter-rouge">_includes/</code></td>
      <td>Same structure for includes</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">_data/</code></td>
      <td><code class="language-plaintext highlighter-rouge">_data/</code></td>
      <td>Same structure for data files</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">.eleventy.js</code></td>
      <td><code class="language-plaintext highlighter-rouge">_config.yml</code></td>
      <td>Configuration file (YAML format)</td>
    </tr>
    <tr>
      <td>Output directory (configurable)</td>
      <td><code class="language-plaintext highlighter-rouge">_site/</code></td>
      <td>Default output directory</td>
    </tr>
  </tbody>
</table>

<h2 id="template-differences">Template Differences</h2>

<p>Eleventy supports multiple template languages, while Rustyll primarily uses Liquid:</p>

<table>
  <thead>
    <tr>
      <th>Eleventy</th>
      <th>Rustyll</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Liquid (.liquid)</td>
      <td>Liquid</td>
    </tr>
    <tr>
      <td>Nunjucks (.njk)</td>
      <td>Converted to Liquid</td>
    </tr>
    <tr>
      <td>Handlebars (.hbs)</td>
      <td>Converted to Liquid</td>
    </tr>
    <tr>
      <td>EJS (.ejs)</td>
      <td>Converted to Liquid</td>
    </tr>
    <tr>
      <td>JavaScript (.11ty.js)</td>
      <td>Needs manual conversion</td>
    </tr>
  </tbody>
</table>

<h3 id="liquid-templates">Liquid Templates</h3>

<p>If you’re already using Liquid templates in Eleventy, the transition will be straightforward:</p>

<table>
  <thead>
    <tr>
      <th>Eleventy (Liquid)</th>
      <th>Rustyll (Liquid)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{{ page.title }}</code></td>
      <td><code class="language-plaintext highlighter-rouge">Migrating from Eleventy</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% for post in collections.posts %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% for post in site.posts %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% include "header.html" %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% include header.html %}</code></td>
    </tr>
  </tbody>
</table>

<h3 id="nunjucks-to-liquid-conversion">Nunjucks to Liquid Conversion</h3>

<p>If you’re using Nunjucks templates, the migrator will convert them to Liquid:</p>

<table>
  <thead>
    <tr>
      <th>Eleventy (Nunjucks)</th>
      <th>Rustyll (Liquid)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{{ page.title }}</code></td>
      <td><code class="language-plaintext highlighter-rouge">Migrating from Eleventy</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% for post in collections.posts %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% for post in site.posts %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% endfor %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% if page.tags contains "featured" %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% include "header.njk" %}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{% include header.html %}</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{% set variable = value %}</code></td>
      <td>``</td>
    </tr>
  </tbody>
</table>

<h2 id="front-matter">Front Matter</h2>

<p>Eleventy front matter is generally compatible with Rustyll:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">title</span><span class="pi">:</span> <span class="s">My Post</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">2023-01-01</span>
<span class="na">tags</span><span class="pi">:</span> 
  <span class="pi">-</span> <span class="s">tech</span>
  <span class="pi">-</span> <span class="s">rust</span>
<span class="na">layout</span><span class="pi">:</span> <span class="s">post</span>
<span class="nn">---</span>
</code></pre></div></div>

<h2 id="collections-and-data">Collections and Data</h2>

<p>Eleventy uses the concept of collections, while Rustyll has both collections and posts:</p>

<table>
  <thead>
    <tr>
      <th>Eleventy</th>
      <th>Rustyll</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">collections.posts</code></td>
      <td><code class="language-plaintext highlighter-rouge">site.posts</code></td>
      <td>Blog posts in Rustyll</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">collections.customType</code></td>
      <td><code class="language-plaintext highlighter-rouge">site.customType</code></td>
      <td>Custom collections in Rustyll</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">{{ collections.all }}</code></td>
      <td><code class="language-plaintext highlighter-rouge">{{ site.pages }}</code> and <code class="language-plaintext highlighter-rouge">{{ site.posts }}</code></td>
      <td>All content</td>
    </tr>
  </tbody>
</table>

<p>Configure collections in Rustyll’s <code class="language-plaintext highlighter-rouge">_config.yml</code>:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll collections (similar to Eleventy collections)</span>
<span class="na">collections</span><span class="pi">:</span>
  <span class="na">projects</span><span class="pi">:</span>
    <span class="na">output</span><span class="pi">:</span> <span class="kc">true</span>
    <span class="na">permalink</span><span class="pi">:</span> <span class="s">/projects/:name/</span>
</code></pre></div></div>

<h2 id="configuration-conversion">Configuration Conversion</h2>

<p>Eleventy uses a JavaScript configuration file, while Rustyll uses YAML:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Eleventy (.eleventy.js)</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">eleventyConfig</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">{</span>
    <span class="na">dir</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">input</span><span class="p">:</span> <span class="dl">"</span><span class="s2">src</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">output</span><span class="p">:</span> <span class="dl">"</span><span class="s2">dist</span><span class="dl">"</span>
    <span class="p">}</span>
  <span class="p">};</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Converts to:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll (_config.yml)</span>
<span class="na">source</span><span class="pi">:</span> <span class="s">src</span>
<span class="na">destination</span><span class="pi">:</span> <span class="s">dist</span>
</code></pre></div></div>

<h2 id="filters-and-shortcodes">Filters and Shortcodes</h2>

<p>Eleventy’s custom filters and shortcodes need to be converted to Rustyll’s plugin system:</p>

<table>
  <thead>
    <tr>
      <th>Eleventy</th>
      <th>Rustyll</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Custom filters in .eleventy.js</td>
      <td>Custom Liquid filters in Rust plugins</td>
    </tr>
    <tr>
      <td>Shortcodes</td>
      <td>Includes or Liquid tags</td>
    </tr>
  </tbody>
</table>

<p>For example, an Eleventy shortcode:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Eleventy</span>
<span class="nx">eleventyConfig</span><span class="p">.</span><span class="nf">addShortcode</span><span class="p">(</span><span class="dl">"</span><span class="s2">user</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">avatar</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="s2">`&lt;div class="user"&gt;
    &lt;img src="</span><span class="p">${</span><span class="nx">avatar</span><span class="p">}</span><span class="s2">" alt="</span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">"&gt;
    &lt;h2&gt;</span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">&lt;/h2&gt;
  &lt;/div&gt;`</span><span class="p">;</span>
<span class="p">});</span>
</code></pre></div></div>

<p>Would become a Rustyll include (<code class="language-plaintext highlighter-rouge">_includes/user.html</code>):</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Rustyll --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"user"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">""</span> <span class="na">alt=</span><span class="s">""</span><span class="nt">&gt;</span>
  <span class="nt">&lt;h2&gt;&lt;/h2&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>Used as: <code class="language-plaintext highlighter-rouge">{% include user.html name="John" avatar="/images/john.jpg" %}</code></p>

<h2 id="performance-optimization">Performance Optimization</h2>

<p>Rustyll offers significant performance improvements over Eleventy:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll performance options</span>
<span class="na">threads</span><span class="pi">:</span> <span class="s">auto</span>  <span class="c1"># Use all available CPU cores</span>
<span class="na">incremental</span><span class="pi">:</span> <span class="kc">true</span>  <span class="c1"># Enable incremental builds</span>
<span class="na">cache</span><span class="pi">:</span>
  <span class="na">enabled</span><span class="pi">:</span> <span class="kc">true</span>
  <span class="na">strategy</span><span class="pi">:</span> <span class="s">aggressive</span>
</code></pre></div></div>

<h2 id="troubleshooting-common-issues">Troubleshooting Common Issues</h2>

<h3 id="javascript-templates-and-functions">JavaScript Templates and Functions</h3>

<p>If you heavily use JavaScript in your Eleventy site:</p>

<ol>
  <li>Convert JavaScript templates to Liquid templates</li>
  <li>Replace custom JavaScript functions with Liquid filters</li>
  <li>Consider using Rustyll plugins for complex functionality</li>
</ol>

<h3 id="pagination-differences">Pagination Differences</h3>

<p>Eleventy and Rustyll handle pagination differently:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># Rustyll pagination</span>
<span class="na">paginate</span><span class="pi">:</span> <span class="m">10</span>  <span class="c1"># Posts per page</span>
<span class="na">paginate_path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/blog/page:num/"</span>
</code></pre></div></div>

<h2 id="migration-checklist">Migration Checklist</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Install Rust and Rustyll</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Back up your Eleventy site</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Run the migration command</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Update templates to use Rustyll’s syntax</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Configure collections</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Create includes for shortcodes</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Test build with <code class="language-plaintext highlighter-rouge">rustyll build</code></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Preview site with <code class="language-plaintext highlighter-rouge">rustyll serve</code></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Check for template errors</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Verify all content renders correctly</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Update deployment workflows</li>
</ul>

<h2 id="need-help">Need Help?</h2>

<ul>
  <li><a href="https://forum.rustyll.com">Rustyll Forum</a></li>
  <li><a href="https://discord.gg/rustyll">Rustyll Discord</a></li>
  <li><a href="https://github.com/rustyll/rustyll/issues">GitHub Issues</a></li>
</ul>
</article>
<nav class="doc-pagination" aria-label="Previous and next pages"><a href="/docs/migrating/docsy-to-rustyll/"><span>← Previous</span>Migrating from Docsy</a><a href="/docs/migrating/fresh-to-rustyll/"><span>Next →</span>Migrating from Fresh</a></nav>
<div class="doc-feedback"><p>Help keep these docs useful.</p>



<a href="https://github.com/betterwebinit/rustyll-website/edit/main/_docs/migrating/eleventy-to-rustyll.md" 
   target="_blank" 
   rel="noopener noreferrer"
   class="inline-flex items-center gap-2 text-sm text-gray-400 hover:text-rust transition-colors duration-200 group px-3 py-1.5 bg-black/20 rounded-md border border-gray-800 hover:border-rust/30 ">
  <svg class="w-4 h-4 transition-transform duration-200 group-hover:rotate-12" fill="none" stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
  </svg>
  <span>Improve this page</span>
</a> </div></div>
</div><aside class="docs-toc">

<nav class="page-toc " aria-label="On this page"><h2>On this page</h2><ul>

<li class="toc-level-2"><a href="#installation">Installation</a></li><li class="toc-level-2"><a href="#automatic-migration">Automatic Migration</a></li><li class="toc-level-2"><a href="#directory-structure-differences">Directory Structure Differences</a></li><li class="toc-level-2"><a href="#template-differences">Template Differences</a><ul><li class="toc-level-3"><a href="#liquid-templates">Liquid Templates</a></li><li class="toc-level-3"><a href="#nunjucks-to-liquid-conversion">Nunjucks to Liquid Conversion</a></li></ul></li><li class="toc-level-2"><a href="#front-matter">Front Matter</a></li><li class="toc-level-2"><a href="#collections-and-data">Collections and Data</a></li><li class="toc-level-2"><a href="#configuration-conversion">Configuration Conversion</a></li><li class="toc-level-2"><a href="#filters-and-shortcodes">Filters and Shortcodes</a></li><li class="toc-level-2"><a href="#performance-optimization">Performance Optimization</a></li><li class="toc-level-2"><a href="#troubleshooting-common-issues">Troubleshooting Common Issues</a><ul><li class="toc-level-3"><a href="#javascript-templates-and-functions">JavaScript Templates and Functions</a></li><li class="toc-level-3"><a href="#pagination-differences">Pagination Differences</a></li></ul></li><li class="toc-level-2"><a href="#migration-checklist">Migration Checklist</a></li><li class="toc-level-2"><a href="#need-help">Need Help?</a></li>
</ul></nav>
</aside></div></section>
</div>
</div>

Search Rustyll

Type to find a page.