Abell (v0.9)

A Static-Site-Generator for
JavaScript Developers

npx create-abell-app my-cool-blog
cd my-cool-blog
npm run dev

Get Started with Starters

Cover image of Blog Starter

Blog Starter

by Abell Team

Use this Starter

or
Create new project locally with:
npx create-abell-app my-app --template abelljs/abell-starter-minima
Cover image of Portfolio Starter

Portfolio Starter

by Abell Team

Use this Starter

or
Create new project locally with:
npx create-abell-app my-app --template abelljs/abell-starter-portfolio

Sponsors

Gold Sponsors

Backers

Become a Sponsor

Why Abell?



New Template Engine to Flatten the Learning Curve and Faster Builds 💅

Abell files are HTML files which allow you to write JS inside curly brackets so you can use JavaScript to loop over data, require static data, and use conditions in the HTML. Styling, client-side scripting and almost everything else stays same as you would do in vanilla HTML.

Input (.abell)

index.abell

{{ 
  const a = 'Hello';
  const b = ', World 🌻';
}}

<html>
  <body>
    I can render JavaScript! 
    Look: {{ a + b.toUpperCase() }}
  </body>
</html>

Output (.html)

index.html

<html>
  <body>
    I can render JavaScript! 
    Look: Hello, WORLD 🌻
  </body>
</html>

Edit abell-hello-world

Output What is Needed

Abell builds a static website for you on abell build so if your website does not need any client-side JavaScript, Abell will not add any JavaScript in your project!

For example, if we don't have any CSS and script in the code, this is what the output will look like:

Input

  • index.abell
  • Nav.abell
  • Footer.abell
  • Meta.abell

Output

HTML logo index.html

Control Over Bundling!

Have a critical CSS/JS that needs to load as soon as user visits the page? With Abell you can inline a CSS or JavaScript from component!

{{
  const TestFooter = require('./components/TestFooter.abell');
}}

<html>
<body>
  <footer>
    This footer will be unaffected by the styles in Footer component since they are scoped.
    <span class="year">This span will be ignored as well</span>
  </footer>

  <TestFooter />
</body>
</html>














Control Over Bundling

Output

<html>
<head>
  <style>
  /* Styles are inlined because of 'inlined' attribute in component */

  footer[data-abell-hCdFua] {
    background-color:#111;
    color:#fff;
    padding:10px 20px;
  }
  </style>
</head>
<body>
  <footer>
    This footer will be unaffected by the styles in Footer component since they are scoped
    <span class="year">This span will be ignored as well</span>
  </footer>
  <footer data-abell-hCdFua>© Abell <span class="year" data-abell-hCdFua></span></footer>

  <!-- JS from component, goes into this file -->
  <script src="./bundled-js/footer.js"></script>
</body>
</html>
// this line is injected by Abell
const scopedSelector = (queryString) => document.querySelector(queryString + '[data-abell-hCdFua]');const scopedSelectorAll = (queryString) => document.querySelectorAll(queryString + '[data-abell-hCdFua]'); 

// Your JavaScript
scopedSelector('.year').innerHTML = new Date().getFullYear();
  

Build JSON Based Websites { }

If you have a portfolio and you're bored of writing code to add new project, you can have all the info of your projects in a JSON file and render the list in Abell 🥳

{{ const siteData = require('./site.json'); }}
<html>
  <head>
    <title>{{ siteData.title }}</title>
  </head>
  <body>
    {{
      siteData.projects
        .map(project => 
          `<div>${project.name}</div>`
        )
    }}
  </body>
</html>
{
  "title": "This is my Title",
  "projects": [
    {
      "name": "My cool project",
      "description": "Look at this cool project"
    },
    {
      "name": "Another project",
      "description": "This is another project"
    }
  ]
}

Output

./dist/projects.html

<html>
  <head>
    <title>This is my Title</title>
  </head>
  <body>
    <div>My cool project</div>
    <div>Another project</div>
  </body>
</html>

Edit read-json

Make Use of Node.js Ecosystem

Though there is a way to create Abell Plugins, in most of the cases you can completely remove that abstraction and make use of Node.js directly from your Abell file.

{{
  // Native Node.js Modules
  const fs = require('fs');
  const path = require('path');

  // NPM Library 🤯 https://npmjs.org/package/remarkable
  const { Remarkable } = require('remarkable');
  const md = new Remarkable();
}}

<html>
<body>
  {{
    const markdownPath = path.join(__dirname, 'introduction.md');

    // Read Markdown Content and render it to HTML with Remarkable
    md.render(fs.readFileSync(markdownPath, 'utf-8'))
  }}
</body>
</html>
# Hello from Markdown

![Abell Logo](https://abelljs.org/favicon.ico)

This text is coming from 
[Markdown File](https://en.wikipedia.org/wiki/Markdown) 
in `theme/introduction.md`

Don't know how to implement something in Abell? 
Search for how to implement it in Node.js and 
most of the things will just work out of the box









Output

./dist/index.html

Edit vanilla-node-markdown



And a lot more!!

Get Started with Abell for complete documentation 🐨🎉



GitHub Contributors

Check out GitHub @abelljs for list of repositories, every repo has a README for contribution guide