File System
On the instant browser runtime, your app's files are virtual. You can explore and select (open) files in the FileTree to the left.
File Tabs
If a file is open, it will appear in the FileTabs component above the editor.
When a file is selected, the tab will be underlined and open in the editor.
File Tab Actions
Files that appear in the File Tab component can be
- Clicked to be selected and opened in the editor
- Dragged / dropped to be re-ordered
- Closed by clicking the 'x'
File Tree
The file tree display's all files and folders for your app.
Folders
Folders can be expanded or collapsed by clicking the chevron to the left.
Files
You can open and select a file by clicking on it in the tree.
Template Files
Apps start from templates, so there are some files and folders that cannot be changed.
This means they cannot be renamed, moved, updated or deleted.
File and Folder Actions
The user has full control over any file or folder they create.
There is a menu to add a new file or folder at the root level that is always visible directly above the file tree.
Any action available for a file or folder, whether generated by a template or created by a user will be available in a menu that appears on hover to the right of the node (file or folder).
The menu will stay visible for 5 seconds before fading out. A mouse hover will make the menu appear again.
Any action that is not available, the option will not be displayed.
Like any code editor, you are able to:
-
Create a new File or Folder
-
Rename some generated and all created Files and Folders
-
Delete some generated and all created Files and Folders
Image and File Upload
Upload a file (image, PDF, or any other file type) using the upload icon next to New File / New Folder — at the root of the file tree, or on hover next to any folder. You can also drag a file from your computer directly onto the tree (or onto a specific folder) to upload it there.
Uploaded files appear in the tree as asset nodes. Clicking one opens a preview tab instead of the code editor (images render inline; other file types offer an "Open in new tab" link).
Reference an uploaded image from your code exactly like any other import:
import logo from '@/src/assets/logo.png';<img src={logo} alt="Logo" />This resolves to the file's URL — the same behavior as a real bundler like Vite, not inlined bytes.
Images are capped at 10MB; other file types at 25MB.
Module Resolution
cdbx has a custom bundler that makes module resolution easy.
Support for es modules
cdbx supports the use of es module syntax: import / export.
Support for commonJS modules
cdbx also has support for commonJS module syntax: require().
Local Files
cdbx gives you a lot of freedom over how you write your code. At some points during development however, certain design decisions needed to be taken.
Design Decision
It is a requirement in cdbx to use of a full path using @/ at the beginning of an import statement for a local file.
A local file is any file in your app, either generated by the template or created by the user.
So that means if you want to import a component from a file in cdbx all you have to do is:
import App from '@/src/App';It's just as easy for other types of files such as css:
import '@/src/styles.css';Managing Dependencies
cdbx has a built-in bundler that fetches npm packages on demand — no npm install, and nothing to declare up front. Just write an import and the bundler handles the rest. (There is a package.json in the file tree, but it's generated from your imports rather than read — see About that package.json below.)
Importing packages
Use standard ES module or CommonJS syntax:
// ES modules
import React from 'react';
import { useState } from 'react';
// CommonJS
const lodash = require('lodash');Any package available on unpkg (opens in a new tab) can be imported this way.
Version pinning
Append @version to the package name to pin a specific version:
import React from 'react@19';
import { createRoot } from 'react-dom@19/client';
import lodash from '[email protected]';Without a version specifier, the bundler fetches the latest available version. Pinning is recommended for reproducibility — an unpinned import may break if the package publishes a breaking release.
Template starter files always pin their versions. The AI assistant reads those pins and matches them when generating new files, so generated code stays compatible with your existing dependencies.
How import resolution works
When the bundler sees an import like import React from 'react@19':
- It checks the in-browser package cache first
- If not cached, it fetches the package from
unpkg.com/react@19 - The resolved module is cached for the session — subsequent imports of the same package (across files) use the cached copy
Sub-path imports work the same way:
import { BrowserRouter } from 'react-router-dom@6/dist/react-router-dom.development.js';About that package.json
You'll see a package.json in the file tree. It's worth knowing that it works backwards from the one you're used to: cdbx writes it from your code, your code doesn't come from it.
Whenever you edit a file, cdbx scans your imports and rewrites package.json to match — the package name, and the version from your import specifier ('[email protected]' becomes "lodash": "4.17.21", an unpinned import becomes "latest").
So:
- Editing it does nothing. Adding a dependency there won't install anything or make it importable, and your edit is overwritten the next time you change any other file. To add a package, just write the import — that's the whole step.
- The version that matters is the one in your import, not the one in
package.json.
It's there so your app reads like a normal project when you export it, so the AI can see your dependencies at a glance, and so upgrading to a real server knows what to install for real.
If you want a package.json that actually drives installs, ask for one — that's what triggers the upgrade described on that page, with real npm install and real node_modules.
Local file imports
Always use the @/ prefix for local files (files in your app):
import App from '@/src/App';
import '@/src/styles.css';
import { utils } from '@/src/lib/utils';The @/ prefix maps to the root of your app. This is required — relative imports (../App) are not supported.
Managing Resources
The user does not have access to the full html file (opens in a new tab), however, users are able to access the <head> (opens in a new tab) in order to:
- add resources such as a
linkfor css stylesheets, - add a
scriptfor external javascript - add metadata such a
titleordescription, - set an
author,viewport,charset,keywords, - custom
styletags - add google fonts...
- etc.
Or body (opens in a new tab) of the html template.
When the index.html file is open in the editor, the following template is generated:
<html>
<head>
<!-- user head content goes here -->
</head>
<body>
<!-- user body content goes here -->
</body>
</html>Anything the user places between the <head> and </head> tags will be added to the actual document head.
And anything the user places between the <body> and </body> tags will be added to the actual document body.
Accessing App Metadata and Settings
TODO: This is not supported yet but will be available soon.
App metadata and settings are (will be) available through the cog menu above the browser.