Private betav0.1.0
Docs
Format developer documentation

Project structure

The file structure of a Format Studio project.

Studio tries to strike a balance of opinionated file structure and flexibility. This makes assets, test data and schema easy to work with, whilst allowing you to build creatively, using your own approach to organizing your components and styles.

To create a document directory that follows this structure, run format new.

Directory structure

This is the directory structure for a bare bones Studio project.

documents
invoice
data
default.json
schema.ts
assets
banner.png
index.tsx
shared-assets
logo.png
.env
format.config.json
package.json
tsconfig.json
documents
invoice
data
default.json
schema.ts
assets
banner.png
index.vue
shared-assets
logo.png
.env
format.config.json
package.json
tsconfig.json
documents
invoice
data
default.json
schema.ts
assets
banner.png
index.html
index.ts
shared-assets
logo.png
.env
format.config.json
package.json
tsconfig.json

documents

This directory houses your documents. A document is the source for a PDF. Each document can have different data variations or even template and style variations based on data you pass in. The name is not configurable, so documents as a directory name is reserved. However, you can change the location of this directory using therootDir.

Examples of documents could be:

  • Invoice
  • Bank statement
  • 2026 catalog

Variations of the same document can generally be managed with the data you pass in. If the template differs dramatically, you could opt for separate documents and share layout components in code.

documents/[invoice]

An example of a document. You can structure this directory however you like but you must expose an index entry point for the document, which exports a default module.

documents/[invoice]/index.{ts|tsx|vue}

documents/invoice/index.tsx
import { Document, Layout } from '@format.dev/react'

export default function Invoice ({ data }) {
	return (
		<Document title="Invoice">
			<Layout id="invoice" width={793.71} height={1122.52}>
				Invoice
			</Layout>
		</Document>
	)
}
documents/invoice/index.vue
<script setup lang="ts">
import { Document, Layout } from '@format.dev/vue'
</script>

<template>
	<Document title="Invoice">
		<Layout id="invoice" :width="793.71" :height="1122.52">
			Invoice
		</Layout>
	</Document>
</template>
documents/invoice/index.ts
export { default } from './index.html'
documents/invoice/index.html
<template data-type="document" data-title="Invoice">
	<template data-type="layout" data-id="invoice" data-width="793.71px" data-height="1122.52px">
		Invoice
	</template>
</template>

documents/[invoice]/data

The data directory inside a document contains JSON files, each a data variant to test your document against. The name is not configurable, so data as a directory name is reserved. Read more about data and variants.

documents/[invoice]/assets

The assets directory is for your document-specific assets. You can think of this like a public directory on a web server. For example, putting logo.png inside assets can be referenced in your templates as:

<img src="./logo.png">

The name is not configurable, so assets as a directory name is reserved. You can read more about assets here.

shared-assets

If you have assets that are used by multiple documents, you can specify a shared assets directory. The name and location is configurable using sharedAssetsDir.

You can read more about assets here.

format.config.json

This is the configuration file for Studio. You can read more about the available options in the configuration section.

.env

Studio exposes a few environment variables you can use:

VariablePurpose
PORTControls the port Studio runs on. Also configurable via the --port flag
FORMAT_API_KEYYour Format API key. Required to generate PDFs in Studio
FORMAT_DEBUGShows more verbose logs to help pinpoint bugs. Values: true | false

The location of .env is configurable: dotEnvPath

Document naming

Studio lists each document by its directory name. When you bundle and generate PDFs in code, the directory name is converted to camelCase and used as the document's export name. See the Renderer API for the naming table and import examples.

Was this page helpful?