Skip to content

Data Import & Export

Rebase includes built-in data import and export tools accessible directly from the admin panel. Import supports CSV, JSON, and Excel files with a column-mapping wizard. Export supports CSV and JSON with optional computed fields.

Both are available on every collection. Export can be configured per collection with computed fields, or switched off with exportable: false; import cannot be switched off per collection.

  1. Open a collection in the admin panel
  2. Click the Import button in the toolbar
  3. Select or drag-and-drop your file
  4. Map file columns to collection properties
  5. Preview the data, including any values that cannot be converted
  6. Click Save data to write the rows
Format Extensions Notes
CSV .csv Auto-detects delimiters
JSON .json Expects an array of objects
Excel .xlsx Reads the first sheet

The import wizard automatically attempts to match file columns to collection properties by name. You can manually adjust mappings before importing:

  • Exact matches are mapped automatically (e.g. name → name)
  • Unmatched columns can be mapped manually or skipped
  • Type conversion turns each cell into the type of the property it maps to, but only when nothing is lost (see below)

A cell is converted only when the property’s type can hold exactly what it says:

Property type Converts Does not convert
Number 12, -3.5, 10.00, 1e3 02134 (a leading zero would be lost), numbers with more than 15 significant digits, 1,234, $5.00, 12%, N/A
Boolean true/false, yes/no, y/n, 1/0, in any case anything else
Date ISO 8601 (2024-01-05, 2024-01-05T10:00:00Z), written-out dates (5 Jan 2024), 05/01/2024, epoch seconds or milliseconds text that names no date
Geopoint the object the export writes, {"latitude": 41.9, "longitude": 12.5}, or its JSON in a CSV cell anything else, or a coordinate out of range
Map without declared fields an object, or its JSON in a CSV cell anything else
Vector a list of numbers ([0.1, 0.2], 0.1, 0.2), or the export’s {"value": [0.1, 0.2]} a list holding anything that is not a number

A date without a time is that day in UTC. For dates written as 05/01/2024, the column decides the order: a first number above 12 makes the column day-first, a second number above 12 makes it month-first. When a column never says, the browser’s locale decides, and when it holds both orders, a date that either order could read is not converted.

A blank cell is no value: it sets nothing, and the default you chose for that property applies.

A file exported from a collection imports back into the same values, CSV or JSON. A map with declared fields is read one column per field (address.street), as the export writes it; any other value, a geopoint or a key-value map included, is one column. An epoch number between -100,000,000,000 and 100,000,000,000 is read as seconds, so a date between 31 October 1966 and 3 March 1973 exported as a timestamp does not come back: export those dates as text. A time-of-day field reads a number below one day (86,400,000) as the milliseconds since midnight the export writes.

The preview lists every cell that does not convert, per column, with how many there are and the first few by row and reason. Those cells are left empty in the imported rows; nothing is turned into 0, false or an empty value without being listed. Go back to map the column to another property, or correct the file and upload it again.

The collection’s own rules — required fields, enum options, unique values — are checked by the server as the rows are written, in batches of up to 500 rows (fewer when the rows are wide, so a request stays under about 1 MB). A batch is saved whole or not at all. If a row is refused, the import stops and names it; the batches before it are already saved, and Retry resumes from the first row of the refused row’s batch.

A row whose id is already in the collection updates that record: the columns the file carries are written, and the others keep their stored values, so a file of id,price reprices existing products without repeating their required fields. A new row still needs every required field. A batch that mixes updates and new rows is written as two requests, so a refused new row can leave that batch’s updates saved; Retry writes them again with the same values.

A new row in the users collection is a user creation: a password column is hashed, never stored as written, and a row without one gets a generated password or an invitation, as when an administrator adds a user. The passwords in such a file were usually set under another system’s rules, so the import asks the server to skip the password policy for those rows. The server agrees only when you are an administrator; anyone else importing users is held to the policy, and a weak password stops the import with WEAK_PASSWORD.

When you create a collection from a file, each column’s type is inferred from its values. A column is a number only if every value in it is a number or text that converts to one exactly, so a column of zip codes, product codes with leading zeros, long SKUs or phone numbers stays text. A column that mixes types (numbers and words, booleans and numbers) is text. Blank cells do not count, so a mostly empty column is not marked required. A column of whole numbers whose name ends in a word that says it holds a moment (created_at, updatedAt, signup_date, timestamp) is a date when every value is an epoch timestamp of 2001–2103, in seconds or milliseconds; under any other name, or with any other value, it stays a number.

Import is available on every collection. There is no per-collection setting that turns it off.

  1. Open a collection in the admin panel
  2. Optionally apply filters to export a subset of data
  3. Click the Export button in the toolbar
  4. Choose the format: CSV or JSON
  5. The file downloads immediately
Format Description
CSV Comma-separated values, compatible with Excel and Google Sheets
JSON Array of objects, useful for programmatic consumption

Any active filters in the collection view are applied to the export. This lets you export only a subset of your data:

  • Apply column filters or search terms in the collection view
  • Click Export — only the filtered rows are included

Export is available on every collection unless you turn it off. admin.exportable configures it: exportable: false removes the Export button, and an ExportConfig keeps it and adds computed columns, below.

Use the ExportConfig object to add custom computed columns to your exports. These columns don’t exist in the database — they are calculated at export time:

import { defineCollection } from "@rebasepro/cms-types";
const productsCollection = defineCollection({
slug: "products",
table: "products",
name: "Products",
properties: { /* ... */ },
admin: {
exportable: {
additionalFields: [
{
key: "computed_margin",
builder: ({ entity }) => {
const price = entity.values.price as number;
const cost = entity.values.cost as number;
return String(price - cost);
}
},
{
key: "full_url",
builder: ({ entity }) => {
return `https://mystore.com/products/${entity.id}`;
}
}
]
}
}
});

Each additionalFields entry has:

Property Type Description
key string Column name in the export
builder ({ entity, context }) => string | Promise<string> Function that computes the value

The builder function receives the current entity and the RebaseContext (which includes the authenticated user), so you can compute values based on both data and permissions.

The builder function can be async, which is useful when the computed value requires a database lookup or API call:

exportable: {
additionalFields: [
{
key: "author_name",
builder: async ({ entity, context }) => {
const author = await context.data.users.findById(
entity.values.authorId as string
);
return author?.values.displayName ?? "Unknown";
}
}
]
}