Literate Notebooks

BioLang notebooks (.bln files) interleave Markdown prose with executable BioLang code. They're perfect for documenting analyses, creating reproducible reports, and sharing results with collaborators.

Quick Start

No installation needed

Use the browser notebook for core BioLang, statistics, tables, and browser-safe plots. Your local files are read in the browser and are not uploaded. Statistics workbooks fetch their small teaching-data package only when they import it.

Open browser notebook →
# Run a notebook in the terminal
bl notebook analysis.bln

# The general runner auto-detects .bln and .bl.md too
bl run analysis.bln

# Export to standalone HTML
bl notebook analysis.bln --export html

# Convert from Jupyter
bl notebook experiment.ipynb --from-ipynb > experiment.bln

# Convert to Jupyter
bl notebook experiment.bln --to-ipynb > experiment.ipynb

Browser Notebook

The standalone notebook page opens local .bln files or public URLs, lets you edit and reorder cells, and saves back to plain text. Interpreter state is shared across code cells. If you run a later cell first, the browser runs the required earlier code cells before it.

Code cells are checked by the same parser service used by BioLang WASM and the native language server. Syntax errors appear below the cell before you run it; execution errors still appear in that cell's output.

Add ?url= with an encoded public notebook URL to make a direct-open link. The remote host must permit browser requests with CORS. Relative data and image links are resolved from the notebook URL; local data can be added with Attach data files. Regular GitHub /blob/ file links are converted to their raw form automatically.

Runs in the browserUse the native CLI
Core language, browser-safe builtins, and statistics; optional statdata downloads on demandOther installed packages and plugins
Small local text datasetsLarge files, directories, and unrestricted filesystem access
Inline tables and SVG plotsGPU, containers, subprocesses, and native libraries

The .bln Format

A .bln file is plain text. Markdown prose is rendered, and code blocks are evaluated. Interpreter state carries over between blocks — variables defined in one block are available in all later blocks.

Fenced Code Blocks

Use standard Markdown fenced code blocks with biolang, bl, or no language tag:

## Sample Quality Control

Load the FASTQ file and check basic statistics.

```biolang
let reads = read_fastq("sample_R1.fastq.gz")
let stats = read_stats(reads)
println(stats)
```

## Filter Low-Quality Reads

Keep only reads with mean Phred score above 25.

```bl
let filtered = reads |> filter(|r| mean_phred(r.quality) > 25)
println(f"Kept {len(filtered)} of {len(reads)} reads")
```

Dash-Delimited Code Blocks

Alternatively, use --- on its own line to delimit code blocks. This is the original BioLang notebook format:

## Load Data
Read the FASTA file and compute per-sequence GC content.
---
let seqs = read_fasta("contigs.fa")
let gc_table = seqs |> map(|s| {id: s.id, gc: gc_content(s.seq)}) |> table()
print(gc_table)
---
## Results
The table above shows GC content per contig.

You can mix both styles in the same notebook. Code blocks with other language tags (e.g. ```python) are treated as prose and displayed but not executed.

Cell Directives

Add special comment annotations at the top of a code block to control how it behaves:

Directive Effect
# @hide Execute the code but don't display it in output. Useful for setup code.
# @skip Don't execute this block. Useful for draft or commented-out cells.
# @echo Print the code before executing it. Shows both code and output.
# @hide-output Execute the code (and show it) but suppress any printed output.

Directives are stripped from the code before execution. You can combine them:

```biolang
# @echo
# @hide-output
let config = {min_quality: 30, threads: 8}
let reference = "GRCh38"
```

HTML Export

Export a notebook to a self-contained HTML file with syntax highlighting and a dark-themed design:

bl notebook analysis.bln --export html > report.html

The HTML output includes inline CSS styling, BioLang syntax highlighting with color-coded keywords, strings, comments, and pipe operators. It's a single file with no external dependencies — perfect for sharing via email or publishing.

Jupyter Interop

Convert between BioLang's .bln format and Jupyter's .ipynb format for compatibility with the Jupyter ecosystem.

Import from Jupyter

# Convert .ipynb to .bln (prints to stdout)
bl notebook experiment.ipynb --from-ipynb > experiment.bln

Markdown cells become prose sections. Code cells are wrapped in fenced ```biolang blocks. Outputs are discarded (they'll be regenerated when you run the notebook).

Export to Jupyter

# Convert .bln to .ipynb (prints to stdout)
bl notebook analysis.bln --to-ipynb > analysis.ipynb

Prose sections become Markdown cells. Code blocks become code cells with "language": "biolang" metadata. The resulting notebook uses nbformat v4 and can be opened in JupyterLab, VS Code, or any notebook viewer.

Terminal Rendering

When you run bl notebook file.bln in a terminal, prose sections are rendered with ANSI styling:

  • Headings — bold, underlined, with level indicators
  • Inline code — cyan highlight
  • Bold and italic — ANSI bold/italic
  • Blockquotes — indented with | prefix in dim text
  • Lists — bullet points with indentation

Code blocks are executed in order. Output is interleaved between prose sections, making it easy to follow an analysis step by step.

Example Notebook

Here's a complete .bln notebook demonstrating the key features:

# GC Content Analysis

This notebook analyzes GC content across a set of contigs
and identifies potential outliers.

## Setup

```biolang
# @hide
let min_gc = 0.3
let max_gc = 0.7
```

## Load Data

Read the FASTA file and compute per-sequence statistics.

```biolang
let seqs = read_fasta("contigs.fa")
println(f"Loaded {len(seqs)} sequences")
```

## Compute GC Content

```biolang
# @echo
let gc_values = seqs |> map(|s| gc_content(s.seq))
let mean_gc = mean(gc_values)
let std_gc = stdev(gc_values)
println(f"Mean GC: {mean_gc:.3f} +/- {std_gc:.4f}")
```

## Identify Outliers

Flag contigs with GC content more than 2 standard deviations
from the mean — these may indicate contamination or
horizontal gene transfer.

```biolang
let outliers = seqs
  |> filter(|s| {
    let gc = gc_content(s.seq)
    abs(gc - mean_gc) > 2.0 * std_gc
  })
println(f"Found {len(outliers)} outlier contigs")
outliers |> each(|s| println(f"  {s.id}: GC={gc_content(s.seq):.3f}"))
```

## Summary

> The analysis identified potential contaminant contigs based
> on anomalous GC content. Review these sequences before
> downstream assembly or annotation.

Tips

  • Use # @hide for configuration and imports to keep the narrative clean
  • Use # @echo for key analysis steps so readers see both code and results
  • Use # @skip to temporarily disable expensive computation during development
  • Use # @hide-output when you want to show the code but not its (verbose) output
  • State carries across cells — define variables once and reuse them throughout
  • The HTML export is self-contained: share report.html directly
  • Use --from-ipynb to migrate existing Jupyter notebooks to BioLang