Great news: You get the same polished API documentation experience—without the hosted platform lock-in. Bengal's directives provide equivalent components in pure Markdown, and you control your own infrastructure.
Quick Wins (5 Minutes)
Core Similarity
Both tools focus on beautiful API documentation with rich components. The main difference: Mintlify uses hosted MDX with JSX components; Bengal uses self-hosted Markdown with directives.
| Mintlify | Bengal | Status |
|---|---|---|
<Note> |
:::{note} |
✅ Direct equivalent |
<Warning> |
:::{warning} |
✅ Direct equivalent |
<Tip> |
:::{tip} |
✅ Direct equivalent |
<Info> |
:::{info} |
✅ Direct equivalent |
mint.json |
bengal.toml |
✅ Similar purpose |
| MDX files | Markdown files | ✅ Simpler |
Component → Directive Translation
Callouts / Admonitions
<Note>
This is a note callout in Mintlify.
</Note>
<Warning>
This is a warning with important information.
</Warning>
<Tip>
A helpful tip for your users.
</Tip>
<Info>
Additional context or information.
</Info>
:::{note}
This is a note callout in Bengal.
:::
:::{warning}
This is a warning with important information.
:::
:::{tip}
A helpful tip for your users.
:::
:::{info}
Additional context or information.
:::
Tip
No imports, no JSX, no closing tags to match. Just clean markdown.
Cards and Card Groups
<CardGroup cols={2}>
<Card title="Quickstart" icon="rocket" href="/quickstart">
Get started in under 5 minutes
</Card>
<Card title="API Reference" icon="code" href="/api-reference">
Explore our API endpoints
</Card>
<Card title="SDKs" icon="cube" href="/sdks">
Official client libraries
</Card>
<Card title="Examples" icon="lightbulb" href="/examples">
Sample code and tutorials
</Card>
</CardGroup>
:::{cards}
:columns: 2
:::{card} Quickstart
:icon: rocket
:link: /quickstart/
Get started in under 5 minutes
:::{/card}
:::{card} API Reference
:icon: code
:link: /api-reference/
Explore our API endpoints
:::{/card}
:::{card} SDKs
:icon: cube
:link: /sdks/
Official client libraries
:::{/card}
:::{card} Examples
:icon: lightbulb
:link: /examples/
Sample code and tutorials
:::{/card}
:::{/cards}
Tabs / Code Groups
<Tabs>
<Tab title="Python">
```python
import requests
response = requests.get("https://api.example.com/users")
```
</Tab>
<Tab title="JavaScript">
```javascript
const response = await fetch("https://api.example.com/users");
```
</Tab>
<Tab title="cURL">
```bash
curl https://api.example.com/users
```
</Tab>
</Tabs>
:::{tab-set}
:::{tab} Python
```python
import requests
response = requests.get("https://api.example.com/users")
```
:::{/tab}
:::{tab} JavaScript
```javascript
const response = await fetch("https://api.example.com/users");
```
:::{/tab}
:::{tab} cURL
```bash
curl https://api.example.com/users
```
:::{/tab}
:::{/tab-set}
Code Groups (Multi-file examples)
<CodeGroup>
```python Python
print("Hello, World!")
```
```javascript JavaScript
console.log("Hello, World!");
```
```go Go
fmt.Println("Hello, World!")
```
</CodeGroup>
:::{tab-set}
:::{tab} Python
```python
print("Hello, World!")
```
:::{/tab}
:::{tab} JavaScript
```javascript
console.log("Hello, World!");
```
:::{/tab}
:::{tab} Go
```go
fmt.Println("Hello, World!")
```
:::{/tab}
:::{/tab-set}
Accordions
<AccordionGroup>
<Accordion title="What is your refund policy?">
We offer a 30-day money-back guarantee on all plans.
</Accordion>
<Accordion title="How do I cancel my subscription?">
You can cancel anytime from your account settings.
</Accordion>
</AccordionGroup>
:::{dropdown} What is your refund policy?
:icon: question
We offer a 30-day money-back guarantee on all plans.
:::
:::{dropdown} How do I cancel my subscription?
:icon: question
You can cancel anytime from your account settings.
:::
Steps
<Steps>
<Step title="Install the SDK">
```bash
pip install my-sdk
```
</Step>
<Step title="Initialize the client">
```python
from my_sdk import Client
client = Client(api_key="your-key")
```
</Step>
<Step title="Make your first request">
```python
response = client.users.list()
print(response)
```
</Step>
</Steps>
:::{steps}
:::{step} Install the SDK
```bash
pip install my-sdk
```
:::{/step}
:::{step} Initialize the client
```python
from my_sdk import Client
client = Client(api_key="your-key")
```
:::{/step}
:::{step} Make your first request
```python
response = client.users.list()
print(response)
```
:::{/step}
:::{/steps}
API Reference Fields
<ParamField path="user_id" type="string" required>
The unique identifier of the user
</ParamField>
<ParamField body="email" type="string" required>
User's email address
</ParamField>
<ResponseField name="id" type="string">
Unique identifier for the created resource
</ResponseField>
<ResponseField name="created_at" type="string">
ISO 8601 timestamp of creation
</ResponseField>
## Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `user_id` | string | ✅ | The unique identifier of the user |
| `email` | string | ✅ | User's email address |
## Response
| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique identifier for the created resource |
| `created_at` | string | ISO 8601 timestamp of creation |
Note
Bengal uses standard markdown tables for API parameters and responses. For complex API documentation, Bengal's autodoc can generate this from OpenAPI specs automatically.
Configuration Comparison
Basic Config
{
"name": "My API Docs",
"logo": {
"light": "/logo/light.svg",
"dark": "/logo/dark.svg"
},
"favicon": "/favicon.png",
"colors": {
"primary": "#0D9373",
"light": "#07C983",
"dark": "#0D9373"
},
"topbarLinks": [
{
"name": "Dashboard",
"url": "https://dashboard.example.com"
}
],
"topbarCtaButton": {
"name": "Get API Key",
"url": "https://dashboard.example.com/api-keys"
},
"navigation": [
{
"group": "Getting Started",
"pages": ["introduction", "quickstart", "authentication"]
},
{
"group": "API Reference",
"pages": ["api-reference/users", "api-reference/orders"]
}
],
"api": {
"baseUrl": "https://api.example.com"
}
}
[site]
title = "My API Docs"
baseurl = "https://docs.example.com"
theme = "bengal"
[site.logo]
light = "logo/light.svg"
dark = "logo/dark.svg"
# Navigation is auto-generated from directory structure
# Use weight frontmatter for ordering
# OpenAPI integration
[autodoc.openapi]
enabled = true
spec = "openapi.yaml"
output_prefix = "api-reference"
Navigation
{
"navigation": [
{
"group": "Getting Started",
"pages": [
"introduction",
"quickstart",
"authentication"
]
},
{
"group": "Guides",
"pages": [
"guides/webhooks",
"guides/pagination",
"guides/errors"
]
}
]
}
<!-- Auto-generated from structure: -->
content/
├── docs/
│ ├── getting-started/
│ │ ├── _index.md (weight: 10)
│ │ ├── introduction.md (weight: 10)
│ │ ├── quickstart.md (weight: 20)
│ │ └── authentication.md (weight: 30)
│ └── guides/
│ ├── _index.md (weight: 20)
│ ├── webhooks.md (weight: 10)
│ ├── pagination.md (weight: 20)
│ └── errors.md (weight: 30)
<!-- Example _index.md -->
---
title: Getting Started
weight: 10
---
Tip
Nomint.jsonnavigation updates needed! Add a page, and it appears in nav automatically. Useweightfrontmatter to control order.
What You Don't Need Anymore
| Mintlify Requires | Bengal |
|---|---|
| Hosted platform subscription | Self-hosted (free) |
mint.jsonnavigation updates |
Auto-generated from directories |
| JSX/MDX knowledge | Just Markdown |
| Component imports | Built-in directives |
| Mintlify CLI | bengalCLI |
| GitHub App integration | Standard Git workflow |
| Platform-specific features | Open source, extensible |
Feature Comparison
What Bengal Has (Self-Hosted Equivalent)
| Feature | Mintlify | Bengal |
|---|---|---|
| Callouts | <Note>,<Warning> |
:::{note},:::{warning}✅ |
| Tabs | <Tabs> |
:::{tab-set}✅ |
| Cards | <Card>,<CardGroup> |
:::{cards}✅ |
| Steps | <Steps> |
:::{steps}✅ |
| Accordions | <Accordion> |
:::{dropdown}✅ |
| Code blocks | Built-in | Built-in ✅ |
| OpenAPI | Built-in | autodoc (config-based) ✅ |
| Search | Hosted | Built-in index ✅ |
| Analytics | Built-in | Integrate any provider |
| Dark mode | Built-in | Built-in ✅ |
| Versioning | Limited | _versions/folders ✅ |
What's Different (Trade-offs)
| Feature | Mintlify | Bengal | Trade-off |
|---|---|---|---|
| Hosting | Managed | Self-hosted | More control, more responsibility |
| API playground | Interactive | Static | No runtime, use external tools |
| Feedback widget | Built-in | Custom integration | More flexible |
| User auth | Built-in | External | Integrate your own |
| Changelog | Built-in component | Standard pages | Simpler |
| AI features | Built-in | External | Use your own AI tools |
OpenAPI Integration
Mintlify Approach
// mint.json
{
"openapi": "openapi.yaml",
"api": {
"baseUrl": "https://api.example.com"
}
}
Bengal Approach
# config/_default/autodoc.yaml
autodoc:
openapi:
enabled: true
specs:
- path: "openapi.yaml"
output_prefix: "api-reference"
generate_pages: true
Bengal generates API documentation pages automatically from your OpenAPI spec during build. No inline directive needed—configure once and documentation is generated for all endpoints.
Directory Structure Comparison
| Mintlify | Bengal | Notes |
|---|---|---|
docs/root |
content/ |
Content location |
mint.json |
bengal.toml |
Configuration |
openapi.yaml |
openapi.yaml |
Same location works |
images/ |
assets/ |
Static files |
api-reference/ |
content/docs/api-reference/ |
API docs |
snippets/ |
content/_snippets/ |
Reusable content |
What Bengal Adds
<!-- Define once in _snippets/auth-header.md -->
Add your API key to the Authorization header:
`Authorization: Bearer YOUR_API_KEY`
<!-- Reuse anywhere -->
:::{include} /_snippets/auth-header.md
:::
Mintlify has snippets too, but Bengal's are more flexible with filtering.
---
title: API Reference
api_version: "2.0"
base_url: "https://api.example.com/v2"
---
# {{ page.title }}
Current API version: **{{ api_version }}**
Base URL: `{{ base_url }}`
Use variables directly in markdown without JSX. Frontmatter keys are available directly (e.g.,{{ api_version }}) or via{{ page.metadata.api_version }}.
# Validate all links work
bengal health linkcheck
# Check for broken references
bengal health
# Full site analysis
bengal analyze
Catch issues before deployment, not after.
# Fast local dev server with hot reload
bengal serve
# Build for production
bengal build
# No cloud dependency for preview
Migration Steps
- 1
Install Bengal
pip install bengal # or with uv uv add bengal - 2
Create New Site
bengal new site mysite cd mysite - 3
Copy Content
# Copy your Mintlify MDX files cp -r /path/to/mintlify/docs/* content/docs/ # Files will need conversion (see next steps) - 4
Convert MDX to Markdown
Replace JSX components with directives:
Find Replace With <Note>...</Note>:::{note}...:::<Warning>...</Warning>:::{warning}...:::<Tabs>:::{tab-set}<Tab title="X">:::{tab} X<Card title="X">:::{card} X<CardGroup>:::{cards}<Steps>:::{steps}<Accordion>:::{dropdown} - 5
Add Frontmatter
Add ordering to pages that need it:
--- title: Quickstart weight: 20 --- - 6
Update Config
Create
bengal.tomlbased on yourmint.json:[site] title = "My API Docs" baseurl = "https://docs.example.com" theme = "bengal" - 7
Copy Assets
cp -r /path/to/mintlify/images/* assets/ cp /path/to/mintlify/openapi.yaml . - 8
Test
bengal build bengal health linkcheck bengal serve
Migration Checklist
Before You Start
- Install Bengal:
pip install bengal - Export/backup your Mintlify content
- Create new Bengal site:
bengal new site mysite
Content Migration
- Copy MDX files to
content/docs/ - Convert
<Note>to:::{note} - Convert
<Tabs>to:::{tab-set} - Convert
<Card>to:::{card} - Convert
<Steps>to:::{steps} - Convert
<Accordion>to:::{dropdown} - Remove JSX imports and exports
Configuration
- Create
bengal.tomlfrommint.json - Add
weightfrontmatter for ordering - Configure OpenAPI integration if used
Assets
- Copy images to
assets/ - Update image paths in content
- Copy OpenAPI spec if used
Verify
- Build:
bengal build - Check:
bengal health linkcheck - Preview:
bengal serve
Quick Reference Card
| Task | Mintlify | Bengal |
|---|---|---|
| Install | npm i mintlify |
pip install bengal |
| New site | Dashboard | bengal new site |
| Build | mintlify build |
bengal build |
| Serve | mintlify dev |
bengal serve |
| Deploy | Push to repo | Any static host |
| Note | <Note> |
:::{note} |
| Tabs | <Tabs> |
:::{tab-set} |
| Cards | <CardGroup> |
:::{cards} |
| Steps | <Steps> |
:::{steps} |
Common Questions
Why leave Mintlify?
Common reasons for migration:
- Cost: Self-hosted Bengal is free
- Control: Own your infrastructure and data
- Customization: Full source access for theming
- No vendor lock-in: Standard markdown, deploy anywhere
- Offline development: Full local workflow
What about the API playground?
Mintlify's interactive API playground doesn't have a direct Bengal equivalent. Options:
- Link to external tools (Postman, Insomnia)
- Embed Swagger UI
- Use static code examples (often clearer anyway)
- Build a custom solution
Can I keep my OpenAPI integration?
Yes! Bengal supports OpenAPI specs:
# config/_default/autodoc.yaml
autodoc:
openapi:
enabled: true
specs:
- path: "openapi.yaml"
output_prefix: "api"
Bengal generates API documentation pages automatically during build. Configure the OpenAPI spec path and output location, and all endpoints are documented.
What about analytics and feedback?
Integrate any analytics provider you prefer:
- Google Analytics
- Plausible
- Fathom
- PostHog
Add the script to your theme's base template. You have full control.
How do I handle authentication/gating?
Bengal generates static HTML. For protected docs:
- Use your hosting platform's auth (Netlify, Vercel)
- Deploy behind a reverse proxy
- Build a custom solution
- Consider Bengal for public docs, separate tool for private
Next Steps
- Directives Reference - All available directives
- Writer Quickstart - Full markdown guide
- Configuration Reference - Config options
- OpenAPI Autodoc - API doc generation