Documentation
Getting Started
Hanami is a specialized scripting language designed to help you create beautiful reports using dynamic data.
Before you begin, you'll need to download and install the Hanami application and CLI. Visit our downloads page to get the latest version for your operating system.
You can also download an example report here.
Upload the .json file to your Hanami editor and build it to see the results.
Basic Syntax
Hanami uses a clean, intuitive syntax that's easy to learn.
Variables
Variables are declared using the let
keyword:
Variable Declaration
Declare variables with the let keyword:
let global_endpoint = "api.com"
let httpheaders = { a: b, c: d }
Document Structure
Every Hanami report starts with a document declaration, which serves as the entry point for your report.
Every Hanami report starts with a document
declaration, which serves as the entry point for your report (similar to a main()
function in other languages):
Document Declaration
Basic document structure with metadata:
document main {
author "John Doe"
date "2025-01-01"
Content goes here
}
The document can include metadata such as the author and date, followed by the content of your report.
Sections
Sections are the building blocks of a Hanami report.
Sections are the building blocks of a Hanami report. They can contain various elements such as titles, subtitles, tables, charts, and lists:
Section Definition
Create sections with various content elements:
let testsection = section {
title "New Title"
subtitle "Test Subtitle"
table {
headers ["a", "b", "c"]
rows [
["a", "b", "c"],
["d", "e", "f"]
]
}
}
Sections can be defined separately and then included in the document using the spread operator (...
):
Using Sections in Documents
Include sections in your document:
document main {
author "John Doe"
date "2025-01-01"
...testsection
}
Tables
Tables are a common way to present data in Hanami.
Tables are a common way to present data in Hanami. They consist of headers and rows:
Table Definition
Create tables with headers and rows:
let secondsection = section {
title "Second Section"
subtitle "Test Subtitle"
table {
headers ["a", "b", "c"]
rows [
["a", "b", "c"],
["d", "e", "f"],
["g", "h", "i"],
["j", "k", "l"],
["m", "n", "o"]
]
}
}
Tables can be included in sections and will be rendered with proper formatting in the final report.
Charts
Hanami supports creating charts from data.
Hanami supports creating charts from data. You can define chart data and then use it in a section:
Chart Creation
Create bar and pie charts:
let barChart = section {
title "Sales by Quarter"
chart {
type "bar"
labels ["Q1", "Q2", "Q3", "Q4"]
data [10000, 15000, 12000, 18000]
}
}
let pieChart = section {
title "Revenue Distribution"
chart {
type "pie"
labels ["Product A", "Product B", "Product C"]
data [45, 30, 25]
}
}
document main {
...barChart
...pieChart
}
Charts can be customized with different types, labels, and data values. Hanami supports various chart types including bar, line, pie, and more.
Images
Hanami provides several ways to include images in your reports.
Hanami provides several ways to include images in your reports:
Image Functions
Different ways to embed images:
coverimage("https://picsum.photos/id/237/200/300", 100, 200)
embeddedimage("local", "https://picsum.photos/id/237/200/300", 100, 200)
embeddedimage("http", "https://picsum.photos/id/237/200/300", 100, 200)
The coverimage
function adds a cover image to your report, while embeddedimage
embeds an image within the report content. Both functions take parameters for the image source and dimensions.
Lists
Bullet lists can be created within sections.
Bullet lists can be created within sections:
Bullet Lists
Create bullet lists in sections:
let bulletlist = section {
title "Bullet List"
subtitle "Test Subtitle"
bullet_list [
"Item 1",
"Item 2",
"Item 3"
]
}
The bullet_list
function takes an array of strings and renders them as a bulleted list in the report.
Variables
Variables in Hanami can store various types of data.
Variables in Hanami can store various types of data, including strings, numbers, objects, and more complex data structures:
Variable Types
Different types of variables:
let global_endpoint = "api.com"
let httpheaders = { a: b, c: d }
let testsection = section {
title "New Title"
subtitle "Test Subtitle"
}
Variables can be used throughout your Hanami script to store and reuse data, sections, and other elements.
Pipelines
Pipelines in Hanami allow you to process data and return a result.
Pipelines in Hanami allow you to process data and return a result:
Pipeline Processing
Process data with pipelines:
let processedData = pipeline {
let sales = [
{ product: "A", amount: 100 },
{ product: "B", amount: 200 },
{ product: "C", amount: 300 }
]
let total = sales[0].amount + sales[1].amount + sales[2].amount
let average = total / 3
return {
data: sales,
total: total,
average: average,
highest: sales[2].amount,
lowest: sales[0].amount
}
}
let dataSection = section {
title "Sales Analysis"
body "Total Sales: {processedData.total}"
body "Average Sale: {processedData.average}"
body "Highest Sale: {processedData.highest}"
}
Pipelines can contain variable declarations, calculations, and must end with a return
statement that specifies the data to be returned. They are useful for data transformation and preparation before visualization.
Expressions & Variables
Hanami supports various types of expressions and variable assignments for building dynamic reports.
Integer Expressions
Basic integer literals and arithmetic operations:
Integer Expressions
Basic integer literals and arithmetic operations:
// Simple integers
2
8
// Arithmetic with precedence
2 + 2 // Result: 4
(2 + 2) * 2 // Result: 8
Variable Assignment
Use the let keyword to assign values to variables:
let a = 5
a // Returns: 5
let variable = section {
title "value"
subtitle "subtitle"
body "value"
}
Hash Objects & Indexing
Create and access hash objects (key-value pairs):
// Creating hash objects
let hash = { "foo": 5 }
hash["foo"] // Returns: 5
// Complex hash with arrays
let data = {
"a": [1, 2, 3],
"b": "test string"
}
data["b"] // Returns: "test string"
String Interpolation
Embed variables within strings using double curly braces:
let value = "https://google.com"
body "the value is: {{value}} and we like it like this."
JSON Handling
Hanami provides powerful JSON processing capabilities for working with API responses and data files.
Parse JSON from HTTP
Parse JSON data from HTTP API calls:
let response = http("https://jsonplaceholder.typicode.com/posts/1", {
"Accept": "application/json"
})
let parsed = json(response["body"])
Read JSON from File
Load and parse JSON data from local files:
let jsondata = jsonfromfile("./testdata/complicated_json.json")
pretty(jsondata) // Pretty-print the JSON structure
Working with Complex JSON
Handle nested JSON structures and extract specific fields:
// Complex nested JSON
let testJson = { "a": { "b": { "c": "d" } } }
pretty(testJson)
// Extract specific fields from arrays
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
let value = parsed[0] // Get first item
pretty(value)
Data Processing
Transform and filter data for use in reports and visualizations.
Filtering Data with filterkeep
Keep only specific fields from your data:
// Filter HTTP response data
let response = http("https://jsonplaceholder.typicode.com/posts/1", {
"Accept": "application/json"
})
let parsed = json(response["body"])
filterkeep(parsed, ["userId", "id", "title", "body"])
// Filter array data
let keystokeep = ["a", "b"]
let originaldata = [
{ "a": 1, "b": 2, "c": 3 },
{ "a": 4, "b": 5, "c": 6 }
]
filterkeep(originaldata, keystokeep)
Converting Data to Tables
Transform filtered data into table format for display:
// Convert filtered data to table
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
_table(parsed[0]) // Convert first item to table
// Filter and convert to table
let keystokeep = ["a", "b"]
let originaldata = [
{ "a": 1, "b": 2, "c": 3 },
{ "a": 4, "b": 5, "c": 6 }
]
_table(filterkeep(originaldata, keystokeep))
File I/O
Read data from various file formats including CSV, Excel, and JSON.
CSV Files
Load CSV data directly into table format:
csv("testdata/test.csv")
Excel Files
Read specific sheets from Excel workbooks:
excel("testdata/financial.xlsx", "Sheet1")
JSON Files
Load and parse JSON files:
let jsondata = jsonfromfile("./testdata/complicated_json.json")
pretty(jsondata)
Imports & Modules
Hanami supports modular programming through imports, allowing you to use built-in modules and custom libraries.
Built-in Modules
Import and use built-in modules:
// Math module
import "math"
math.add(1, 2) // Returns: 3
// Custom test module
import "test"
test.helloworld("value")
DataFrame Module
The dataframe module provides advanced data manipulation capabilities:
import "dataframe"
let d = pipeline {
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
let df = dataframe.build_from_json(parsed, ["id", "name"])
return dataframe.to_table(df)
}
document main {
<- d
}
DataFrames
DataFrames provide powerful data manipulation and analysis capabilities similar to pandas or R data frames.
Building DataFrames from JSON
Create DataFrames from JSON data with specific field selection:
import "dataframe"
let d = pipeline {
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
let df = dataframe.build_from_json(parsed, ["id", "name"])
return dataframe.to_table(df)
}
Column Operations
Rename columns and perform column-based operations:
import "dataframe"
let d = pipeline {
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
let df = dataframe.build_from_json(parsed, ["id", "name"])
let newdf = dataframe.renamecol(df, "name", "newone")
return dataframe.to_table(newdf)
}
Counting and Aggregation
Count specific values and create aggregations:
DataFrame Counting
Count specific values and create aggregations:
import "dataframe"
// Count specific values
let count = dataframe.count(df, "userId", "9")
// Count unique values and convert to chart data
let chartData = dataframe.countunique_tochartdata(df, "userId")
DataFrames with Charts
Use DataFrames to create dynamic charts:
DataFrames with Charts
Use DataFrames to create dynamic charts:
import "dataframe"
let d = pipeline {
let response = http("https://jsonplaceholder.typicode.com/posts", {
"Accept": "application/json"
})
let parsed = json(response["body"])
let df = dataframe.build_from_json(parsed, ["id", "name", "userId"])
return df
}
let p = pipeline {
let df = <- d
return chartdata {
type "pie"
x ["9", "10"]
y [
dataframe.count(df, "userId", "9"),
dataframe.count(df, "userId", "10")
]
}
}
let value = section {
chart {
type "pie"
data <- p
}
}
document main {
title "Welcome to test"
author "Sebastian Barry"
...value
}
Built-in Functions
Hanami provides a rich set of built-in functions for common operations.
String Functions
Functions for working with strings:
String Functions
Functions for working with strings:
len("1") // Returns: 1
len("four") // Returns: 4
Display Functions
Functions for formatting and displaying data:
Display Functions
Functions for formatting and displaying data:
// Pretty-print JSON or complex data
pretty(jsondata)
// Create bullet lists in sections
section {
title "Bullet List"
subtitle "Test Subtitle"
body "value"
bullet_list [
"Item 1",
"Item 2",
"Item 3"
]
}
Image Functions
Embed images from URLs:
Image Functions
Embed images from URLs:
httpcoverimage("https://picsum.photos/id/237/200/300")
SQL Integration
Hanami can connect to databases and execute SQL queries to fetch data for your reports.
Supported Databases
- Postgres
- DB2 (in development)
Configuration
Database credentials can be provided through environment variables:
Bash/Shell
Environment Variables (Bash)
Set database credentials in bash/shell:
export DB_USERNAME=""
export DB_PASSWORD=""
export DB_PORT=""
export DB_TYPE=""
export DB_HOST=""
export DB_NAME=""
export DB_SCHEMA=""
export DB_SSL_MODE="require"
PowerShell
Environment Variables (PowerShell)
Set database credentials in PowerShell:
$env:DB_USERNAME=""
$env:DB_PASSWORD=""
$env:DB_PORT=""
$env:DB_TYPE=""
$env:DB_HOST=""
$env:DB_NAME=""
$env:DB_SCHEMA=""
$env:DB_SSL_MODE="require"
Using SQL in Reports
SQL queries can be executed directly within a section:
SQL in Reports
Execute SQL queries in sections:
section newSection {
title "SQL Query Results"
body "This SQL statement below will query the database and return a table with headers and rows of the database."
sql("select * from ...")
}
document test {
...newSection
}
The sql()
function executes the SQL query and renders the results as a table in your report.
Last updated: 7/26/2025