diff --git a/packages/runtime/.gitignore b/packages/runtime/.gitignore
new file mode 100644
index 00000000..d451ff16
--- /dev/null
+++ b/packages/runtime/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local
diff --git a/packages/runtime/example/delete-button/index.html b/packages/runtime/example/delete-button/index.html
new file mode 100644
index 00000000..7e5d5339
--- /dev/null
+++ b/packages/runtime/example/delete-button/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ meta-ui runtime example: delete button
+
+
+
+
+
+
diff --git a/packages/runtime/package.json b/packages/runtime/package.json
new file mode 100644
index 00000000..8ae4e6bf
--- /dev/null
+++ b/packages/runtime/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@meta-ui/runtime",
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite"
+ },
+ "dependencies": {
+ "react": "^17.0.0",
+ "react-dom": "^17.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^17.0.0",
+ "@types/react-dom": "^17.0.0",
+ "@vitejs/plugin-react-refresh": "^1.3.1",
+ "typescript": "^4.3.2",
+ "vite": "^2.3.8"
+ }
+}
\ No newline at end of file
diff --git a/packages/runtime/src/App.tsx b/packages/runtime/src/App.tsx
new file mode 100644
index 00000000..d5c70f5b
--- /dev/null
+++ b/packages/runtime/src/App.tsx
@@ -0,0 +1,19 @@
+import React, { useState } from "react";
+
+function App() {
+ const [count, setCount] = useState(0);
+
+ return (
+
+ );
+}
+
+export default App;
diff --git a/packages/runtime/src/main.tsx b/packages/runtime/src/main.tsx
new file mode 100644
index 00000000..b1ef1c04
--- /dev/null
+++ b/packages/runtime/src/main.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./App";
+
+ReactDOM.render(
+
+
+ ,
+ document.getElementById("root")
+);
diff --git a/packages/runtime/src/vite-env.d.ts b/packages/runtime/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/packages/runtime/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/runtime/tsconfig.json b/packages/runtime/tsconfig.json
new file mode 100644
index 00000000..013e6c54
--- /dev/null
+++ b/packages/runtime/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
+ "allowJs": false,
+ "skipLibCheck": false,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react"
+ },
+ "include": ["./src"]
+}
diff --git a/packages/runtime/vite.config.ts b/packages/runtime/vite.config.ts
new file mode 100644
index 00000000..8479398e
--- /dev/null
+++ b/packages/runtime/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vite";
+import reactRefresh from "@vitejs/plugin-react-refresh";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [reactRefresh()],
+});