Projects generated by the visual builder use standard Vite/React structure with an additional .lowcode/ metadata folder. This approach ensures:
- ✅ Works with any IDE (VSCode, WebStorm, etc.)
- ✅ Compatible with standard build tools
- ✅ Can be committed to version control
- ✅ Deployable to any hosting platform
- ✅ Visual editor state persisted separately
my-app/
├── .lowcode/ # Visual editor metadata
│ ├── manifest.json # Component architecture
│ ├── connections.json # Data flow connections
│ ├── variables.json # Global reactive variables
│ ├── config.json # Project configuration
│ ├── debug-snapshots/ # Saved debugger states
│ └── plugins/ # Custom plugins
│ └── framework-custom.js
│
├── src/ # Standard source directory
│ ├── components/ # Generated components
│ │ ├── UserCard.jsx
│ │ ├── UserList.jsx
│ │ └── Button.jsx
│ │
│ ├── scripts/ # Custom script nodes
│ │ ├── validateUser.js
│ │ └── formatData.js
│ │
│ ├── runtime/ # Tool runtime (auto-generated)
│ │ ├── globalState.js # Reactive variables system
│ │ ├── debugger.js # Debug wrapper (in debug mode)
│ │ └── connections.js # Component wiring helpers
│ │
│ ├── styles/ # Global styles
│ │ └── globals.css
│ │
│ ├── App.jsx # Main app component
│ └── main.jsx # Entry point
│
├── public/ # Static assets
│ └── favicon.ico
│
├── node_modules/ # Dependencies
│
├── .gitignore
├── package.json
├── vite.config.js
├── tsconfig.json # If TypeScript enabled
└── README.md
Purpose: Complete component architecture and configuration
Structure:
{
"version": "0.1.0",
"metadata": {
"projectName": "My Dashboard",
"framework": "react",
"createdAt": "2025-10-25T10:00:00Z",
"updatedAt": "2025-10-25T15:30:00Z",
"author": "john@example.com"
},
"components": {
"root": {
"id": "root",
"type": "App",
"children": ["header", "main", "footer"]
},
"header": {
"id": "header",
"type": "Header",
"props": {...},
"state": {...},
"children": ["logo", "nav"]
}
},
"routes": [...],
"theme": {...}
}Git: ✅ Commit this - it's the source of truth
Purpose: Visual representation of data flow between components
Structure:
{
"connections": [
{
"id": "conn-1",
"source": {
"componentId": "userList",
"output": "selectedUser"
},
"target": {
"componentId": "userDetail",
"input": "user"
},
"type": "binding"
},
{
"id": "conn-2",
"source": {
"componentId": "submitButton",
"output": "onClick"
},
"target": {
"componentId": "formContainer",
"input": "handleSubmit"
},
"type": "event"
}
],
"layout": {
"userList": { "x": 100, "y": 200 },
"userDetail": { "x": 400, "y": 200 }
}
}Git:
Purpose: Global reactive state definitions
Structure:
{
"currentUser": {
"type": "object",
"reactive": true,
"default": null,
"schema": {
"id": "string",
"name": "string",
"email": "string",
"role": "string"
},
"description": "Currently authenticated user"
},
"theme": {
"type": "string",
"reactive": true,
"default": "light",
"options": ["light", "dark"],
"description": "Application theme"
},
"isAuthenticated": {
"type": "boolean",
"reactive": true,
"default": false,
"description": "User authentication status"
}
}Git: ✅ Commit this - defines app state
Purpose: Tool-specific configuration
Structure:
{
"framework": "react",
"typescript": false,
"formatting": {
"style": "prettier",
"config": {
"semi": true,
"singleQuote": true,
"tabWidth": 2
}
},
"plugins": {
"react": {
"version": "18.2.0"
}
},
"debugger": {
"enabled": true,
"autoCapture": true
},
"sync": {
"mode": "review-required",
"autoSync": false
}
}Git: ✅ Commit this - project settings
Purpose: Saved debugger states for later review
Structure:
debug-snapshots/
├── 2025-10-25-150023.json # Timestamp-based
├── 2025-10-25-151245.json
└── bug-form-submit.json # Named snapshots
Content:
{
"timestamp": "2025-10-25T15:00:23Z",
"event": "onClick",
"component": "submitButton",
"state": {
"components": {...},
"globals": {...}
},
"description": "Form submission bug"
}Git: ❌ Don't commit - local debugging data
Location: src/components/{ComponentName}.jsx
Template:
import React, { useState } from 'react';
/**
* @lowcode:generated
* @lowcode:component-id: userCard
* @lowcode:last-generated: 2025-10-25T10:00:00Z
* DO NOT EDIT: This file is auto-generated. Changes will be overwritten.
* To customize, edit in the visual editor or mark regions as @lowcode:preserve
*/
export default function UserCard({ user, onClick }) {
const [isHovered, setIsHovered] = useState(false);
return (
<div
className="card"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
onClick={onClick}
>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}Comment Markers:
@lowcode:generated- Flag as tool-generated@lowcode:component-id- Link to manifest entry@lowcode:last-generated- Timestamp for change detection@lowcode:preserve- Protect regions from regeneration
Location: src/scripts/{scriptName}.js
Template:
/**
* @lowcode:script-node
* @lowcode:id: validateUser
* This file can be freely edited. It will not be overwritten.
*/
export function validateUser(inputs) {
const { userData } = inputs;
const errors = [];
if (!userData.email?.includes('@')) {
errors.push('Invalid email format');
}
if (userData.password?.length < 8) {
errors.push('Password must be at least 8 characters');
}
return {
isValid: errors.length === 0,
errors
};
}
// Metadata for visual editor
export const metadata = {
name: 'Validate User',
description: 'Validates user input data',
inputs: {
userData: {
type: 'object',
required: true,
schema: {
email: 'string',
password: 'string'
}
}
},
outputs: {
isValid: { type: 'boolean' },
errors: { type: 'array', items: 'string' }
}
};User Editable: ✅ Yes - Script nodes are meant to be customized
Purpose: Reactive global variables system
Auto-generated from .lowcode/variables.json:
/**
* @lowcode:generated
* Global state management - Auto-generated from .lowcode/variables.json
*/
import { create } from 'zustand';
export const useGlobalState = create((set) => ({
// State
currentUser: null,
theme: 'light',
isAuthenticated: false,
// Actions
setCurrentUser: (user) => set({ currentUser: user }),
setTheme: (theme) => set({ theme }),
setIsAuthenticated: (isAuth) => set({ isAuthenticated: isAuth }),
// Reset
reset: () => set({
currentUser: null,
theme: 'light',
isAuthenticated: false
})
}));User Editable: ❌ No - Regenerated when variables.json changes
Purpose: Debug instrumentation (only in debug mode)
/**
* @lowcode:generated
* Debug runtime - Only included in debug builds
*/
class DebugRuntime {
constructor() {
this.isPaused = false;
this.snapshots = [];
}
__debugWrap(name, handler, metadata) {
return async (...args) => {
if (this.isPaused) {
await this.waitForContinue();
}
const preState = this.captureState();
const result = await handler(...args);
const postState = this.captureState();
this.notifyElectron({
type: 'EVENT',
name,
preState,
postState,
metadata
});
return result;
};
}
captureState() {
// Capture component states, globals, etc.
return {...};
}
}
export const debugRuntime = new DebugRuntime();
export const __debugWrap = debugRuntime.__debugWrap.bind(debugRuntime);User Editable: ❌ No - Tool-managed
/**
* @lowcode:generated
* Main application component
*/
import React from 'react';
import Header from './components/Header';
import Main from './components/Main';
import Footer from './components/Footer';
export default function App() {
return (
<div className="app">
<Header />
<Main />
<Footer />
</div>
);
}/**
* @lowcode:generated
* Application entry point
*/
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './styles/globals.css';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);{
"name": "my-dashboard",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"zustand": "^4.4.1"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@vitejs/plugin-react": "^4.2.0",
"eslint": "^8.53.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"vite": "^5.0.0"
},
"lowcode": {
"version": "0.1.0",
"framework": "react"
}
}import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: false,
cors: true
},
build: {
outDir: 'dist',
sourcemap: true
}
});# Dependencies
node_modules
# Build output
dist
*.local
# Debug snapshots (don't commit)
.lowcode/debug-snapshots/
# Editor files
.vscode
.idea
*.swp
*.swo
# OS files
.DS_Store
Thumbs.db
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
- Format: PascalCase
- Extension:
.jsx(or.tsxfor TypeScript) - Examples:
UserCard.jsx,NavigationBar.jsx,Button.jsx
- Format: camelCase
- Extension:
.js(or.tsfor TypeScript) - Examples:
validateUser.js,formatData.js,calculateTotal.js
- Format: kebab-case or camelCase
- Extension:
.css,.scss,.module.css - Examples:
globals.css,button.module.css
- ✅ All visual components
- ✅ One component per file
- ✅ Co-located styles if using CSS modules
- ✅ Non-visual logic components
- ✅ Reusable functions
- ✅ Data transformations
- ❌ Don't edit manually
- ❌ Auto-generated by tool
⚠️ Regenerated on config changes
- ✅ Global styles
- ✅ Theme configuration
- ✅ CSS variables
- Export Bubble app structure
- Map pages → components
- Map workflows → script nodes
- Convert database schemas → API integration
- Export Webflow HTML/CSS
- Parse HTML → component tree
- Convert classes → Tailwind utilities
- Map interactions → React event handlers
- Export Figma components
- Convert frames → div structure
- Map styles → Tailwind classes
- Add interactivity manually
# Build for production
npm run build
# Deploy to Vercel
vercel
# Deploy to Netlify
netlify deploy --prod
# Deploy to AWS Amplify
amplify publishdist/
├── index.html
├── assets/
│ ├── index-a1b2c3d4.js
│ └── index-e5f6g7h8.css
└── favicon.ico
Note: .lowcode/ directory is NOT deployed (development only)
# Backup metadata only
cp -r .lowcode/ .lowcode.backup/
# Full project backup
tar -czf my-app-backup.tar.gz .# Restore metadata
cp -r .lowcode.backup/ .lowcode/
# Regenerate code from manifest
npm run lowcode:regenerate- Commit
.lowcode/manifest.json,variables.json,config.json - Keep components small and focused
- Use script nodes for complex logic
- Document custom code in comments
- Edit
src/runtime/files manually - Commit
debug-snapshots/ - Remove
@lowcode:comment markers - Modify generated code without
@lowcode:preservemarkers
See Also:
- Architecture - How files are generated
- Bidirectional Sync - Managing manual edits
- Component Schema - Manifest format details