---
title: Add your own format
description: Teach jalco-drop to open a new kind of file or folder with its own page, link preview and JSON.
sidebar:
  label: Add your own
---

Every way a drop can open lives in `src/formats/`. There are two kinds.

**Text formats** turn one file into a view, chosen by file name. Markdown, CSV/TSV, HTML and SVG are text formats in `src/formats/text.tsx`, and JSON, JSON Lines and agent sessions are in `src/formats/data.tsx`; anything else that's text falls back to highlighted code. A format's `render` can return `null` when the file isn't what it expected, such as JSON that doesn't parse, and the file opens as highlighted code instead. The **Source** action appears for every text format.

```tsx
export const changelog: TextFormat = {
  id: "changelog",
  test: (name) => /^CHANGELOG\.md$/i.test(name),
  render: async (text) => ({ body: <ReleaseList releases={parseReleases(text)} /> }),
};
```

**Bundle formats** turn a folder into its own page. The CLI zips the folder; the server finds the format's manifest file at the zip's root, and the format decides the page, the link preview, the summary on the card and the JSON agents read. Scrawl (`src/formats/scrawl/`) and Superwhisper (`src/formats/superwhisper/`) are bundle formats.

```tsx
export const superwhisper: BundleFormat = {
  id: "superwhisper",
  manifest: "superwhisper.json",
  load(manifest, entries, root) {
    if (!isNote(manifest)) return null;
    return {
      summary: { title: "Meeting notes", details: ["12:04"] },
      json: (entryUrl) => ({ kind: "transcript", audio: entryUrl(manifest.audio) }),
      Page: (props) => <SuperwhisperPage {...props} note={manifest} />,
    };
  },
};
```

To add one:

1. Create `src/formats/<name>/` with the format, and list it in `src/formats/index.ts`. Order matters: the first format that claims a drop wins.
2. If its page needs to be interactive, add an island in `src/islands/` and register it in `client/islands.tsx`.
3. If the source app writes more than the page needs, teach `bin/jalco-drop` to recognize the folder and write a trimmed manifest, the way it drops Scrawl's window list and Superwhisper's prompt.
4. Add a fixture under `e2e/fixtures/` and a spec, so `npm run check` covers it.
5. Add a page for it under `docs-site/docs/file-types/`, so it shows up in this section of the sidebar.
