Syntax Guide

This page explains the syntax of .abell files

JS-in-HTML Syntax

In .abell files you can write JavaScript code inside the double curly braces.

This code gets evaluated during build-time and the output is injected into HTML.

<body>{{ 2 + 1 }}</body>
// Outputs: <body>3</body>


Imports are allowed in the first block of the file. You can import anything that Vite allows you to import.

  import { add } from './calculate.ts';

<body>{{ add(2, 1) }}</body>

You can also extend the type of files you can import using Vite Plugins. E.g. You can use vite-plugin-md-to-html to use .md imports


In Abell, you can mark a block as declaration block using /** @declarations */ comment

  /** @declarations */
  const a = 3;
  const b = 9;
<body>{{ a + b }}</body>
This is required because in JavaScript, assignments return values which abell might try to print unless /** @declarations */ comment is used

By default Abell tries to print the output of expression inside Abell block. Which means sometimes the default behaviour might be unexpected. E.g. -

  let a;
  a = 4;
<body>{{ a }}</body>

// Outputs - "4<body>4</body>"

This is because in JavaScript, the assignment operator returns the value as well which Abell will try to print unless /** @declarations */ comment is used

Loops & Conditions

You can use .map to loop over array. You can also ternary operators for any conditions.

But... What if I hate writing .map? or using ternary operators in complex conditions?

Immediately Invoked Function Expressions

If you write a function in abell block, It automatically gets invoked with empty params.

Which means if you don't like writing .map or using ternary operators, You can write the good old For loops or if-else conditions inside function and return the value you want to print.


Abell has native component support. It allows you to make your HTML, CSS code reusable.

You can define component starting with _ to tell abell to not create a page of it in final output. You can also opt-out of this _ rule (and file-system routing) by using Custom Routing.

Passing Props

Whenever you import an .abell file, it returns a javascript function that can render the HTML.

The first argument you pass to this function can be read from variable props in the imported file.


<!-- index.abell -->
  import greet from './greet.abell';
  {{ greet({ msg: 'Abell is here!!' }) }}

Now we can read the msg with props.msg in greet.abell file

<!-- greet.abell -->

<h2>{{ props.msg }}</h2>
<!-- Outputs: <h2>Abell is here!!</h2> -->