Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/example-bun/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/

module.exports = {
plugins: ['@stylexjs'],
rules: {
'@stylexjs/valid-styles': 'error',
'ft-flow/space-after-type-colon': 0,
'ft-flow/no-types-missing-file-annotation': 0,
'ft-flow/generic-spacing': 0,
},
};
73 changes: 73 additions & 0 deletions examples/example-bun/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# StyleX with Bun

This example bundles a React app with Bun while compiling StyleX via
`@stylexjs/unplugin`. The unplugin uses its esbuild adapter (Bun’s plugin API is
esbuild-compatible) to compile StyleX at build time, aggregate the generated
styles, and append them to the CSS asset emitted from `src/global.css`.

### Prerequisites

- Bun 1.1+
- `@stylexjs/unplugin`

## Install dependencies

```bash
npm install
```

## Build script (`scripts/build.mjs`)

The production build script wires the unplugin into `Bun.build`:

```js
import stylex from '@stylexjs/unplugin';

await Bun.build({
entrypoints: ['src/main.jsx'],
outdir: 'dist',
metafile: true,
plugins: [
stylex.esbuild({
useCSSLayers: true,
importSources: ['@stylexjs/stylex'],
}),
],
});
```

- `metafile: true` lets the plugin locate CSS assets emitted by Bun.
- `useCSSLayers: true` wraps StyleX output in `@layer` declarations for
predictable specificity.

## CSS entry points

- Production uses `src/global.css` so Bun emits a CSS asset; StyleX appends
aggregated styles during `npm run example:build`.
- Development writes `dist/stylex.dev.css`, which the Bun plugin rewrites on
every StyleX transform so the dev server can hot-reload CSS.

## Dev server integration

The Bun dev server uses `bunfig.toml` with `@stylexjs/unplugin/bun`, which
writes generated StyleX rules into `dist/stylex.dev.css` (marked with
`--stylex-injection`).

`dist/` is generated output and should remain gitignored.

## Commands

```bash
# Production bundle + StyleX CSS extraction
npm run example:build

# Bun dev server with HMR at http://localhost:3000
npm run example:dev

# Serve the generated bundle (run example:build first)
npm run example:start
```

The dev server uses Bun's fullstack mode, bundling `dist/index.dev.html` on
request with `development: true` and the StyleX Bun plugin. Production builds
write `dist/index.html` alongside the bundled assets.
2 changes: 2 additions & 0 deletions examples/example-bun/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[serve.static]
plugins = ["@stylexjs/unplugin/bun"]
24 changes: 24 additions & 0 deletions examples/example-bun/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"private": true,
"name": "example-bun",
"version": "0.17.4",
"description": "Example: StyleX with Bun via @stylexjs/unplugin",
"main": "src/App.jsx",
"scripts": {
"example:build": "bun run scripts/build.mjs",
"example:dev": "bun run scripts/dev.mjs",
"example:start": "bun run scripts/start.mjs",
"example:lint": "eslint \"**/*.{js,jsx}\""
},
"license": "MIT",
"dependencies": {
"@stylexjs/stylex": "0.17.4",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"devDependencies": {
"@stylexjs/unplugin": "0.17.4",
"@stylexjs/eslint-plugin": "0.17.4",
"eslint": "^8.57.1"
}
}
56 changes: 56 additions & 0 deletions examples/example-bun/scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import path from 'path';
import { fileURLToPath } from 'url';
import stylex from '@stylexjs/unplugin';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const entrypoint = path.resolve(__dirname, '..', 'src', 'main.jsx');
const outdir = path.resolve(__dirname, '..', 'dist');
const htmlTemplate = path.resolve(__dirname, '..', 'src', 'index.html');
const htmlOutput = path.resolve(outdir, 'index.html');

async function build() {
const result = await Bun.build({
entrypoints: [entrypoint],
outdir,
target: 'browser',
minify: true,
metafile: true,
plugins: [
stylex.esbuild({
useCSSLayers: true,
importSources: ['@stylexjs/stylex'],
unstable_moduleResolution: {
type: 'commonJS',
rootDir: path.resolve(__dirname, '../../..'),
},
}),
],
});

if (!result.success) {
console.error('Bun build failed.');
for (const message of result.logs) {
console.error(message);
}
process.exit(1);
}

try {
await Bun.write(htmlOutput, await Bun.file(htmlTemplate).text());
} catch (error) {
console.error('Failed to write dist/index.html.');
console.error(error);
process.exit(1);
}
}

build();
36 changes: 36 additions & 0 deletions examples/example-bun/scripts/dev.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import path from 'path';
import { mkdir } from 'fs/promises';
import { fileURLToPath, pathToFileURL } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const distDir = path.resolve(__dirname, '..', 'dist');
const htmlTemplate = path.resolve(__dirname, '..', 'src', 'index.dev.html');
const htmlOutput = path.resolve(distDir, 'index.dev.html');

async function dev() {
await mkdir(distDir, { recursive: true });
await Bun.write(htmlOutput, await Bun.file(htmlTemplate).text());
const homepage = (await import(pathToFileURL(htmlOutput).href)).default;

const port = Number(process.env.PORT) || 3000;

const server = Bun.serve({
port,
development: true,
routes: {
'/': homepage,
},
});

console.log(`Dev server running at http://localhost:${server.port}`);
}
dev();
33 changes: 33 additions & 0 deletions examples/example-bun/scripts/start.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const distDir = path.resolve(__dirname, '..', 'dist');
const port = Number(process.env.PORT) || 3000;

const server = Bun.serve({
port,
async fetch(request) {
const url = new URL(request.url);
const pathname = url.pathname === '/' ? '/index.html' : url.pathname;
const filePath = path.join(distDir, pathname);
const file = Bun.file(filePath);

if (await file.exists()) {
return new Response(file);
}

return new Response('Not found', { status: 404 });
},
});

console.log(`Server running at http://localhost:${server.port}`);
40 changes: 40 additions & 0 deletions examples/example-bun/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import * as React from 'react';
import * as stylex from '@stylexjs/stylex';
import { colors, fonts, sizes } from './globalTokens.stylex';

export default function App() {
return (
<main {...stylex.props(styles.main)}>
<div {...stylex.props(styles.card)}>
<span>StyleX + Bun + unplugin</span>
</div>
</main>
);
}

const styles = stylex.create({
main: {
minHeight: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.gray0,
},
card: {
backgroundColor: colors.blue9,
padding: sizes.spacing5,
borderRadius: sizes.spacing2,
justifyContent: 'center',
display: 'flex',
alignItems: 'center',
color: colors.gray0,
fontFamily: fonts.mono,
},
});
3 changes: 3 additions & 0 deletions examples/example-bun/src/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
--stylex-injection: 0;
}
23 changes: 23 additions & 0 deletions examples/example-bun/src/globalTokens.stylex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import * as stylex from '@stylexjs/stylex';

export const colors = stylex.defineVars({
pink7: '#d6336c',
blue9: '#1864ab',
gray0: '#999',
});

export const fonts = stylex.defineVars({
mono: 'Dank Mono,Operator Mono,Inconsolata,Fira Mono,ui-monospace,SF Mono,Monaco,Droid Sans Mono,Source Code Pro,monospace',
});

export const sizes = stylex.defineVars({
spacing5: '1.5rem',
spacing2: '.5rem',
});
21 changes: 21 additions & 0 deletions examples/example-bun/src/index.dev.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html>
<head>
<title>@stylexjs/unplugin (bun dev)</title>
<meta charset="utf-8" />
<style>
@layer reset {
body {
box-sizing: border-box;
padding: 0;
margin: 0;
}
}
</style>
<link rel="stylesheet" type="text/css" href="./stylex.dev.css" />
</head>
<body>
<div id="root"></div>
<script type="module" src="../src/main.jsx"></script>
</body>
</html>
21 changes: 21 additions & 0 deletions examples/example-bun/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html>
<head>
<title>@stylexjs/unplugin (bun)</title>
<meta charset="utf-8" />
<style>
@layer reset {
body {
box-sizing: border-box;
padding: 0;
margin: 0;
}
}
</style>
<link rel="stylesheet" type="text/css" href="./main.css" />
</head>
<body>
<div id="root"></div>
<script src="./main.js"></script>
</body>
</html>
13 changes: 13 additions & 0 deletions examples/example-bun/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import './global.css';
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';

createRoot(document.getElementById('root')).render(<App />);
2 changes: 1 addition & 1 deletion examples/example-esbuild/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
}
</style>
<link rel="stylesheet" type="text/css" href="./dist/stylex.css" />
<link rel="stylesheet" type="text/css" href="./dist/bundle.css" />
</head>
<body>
<div id="root"></div>
Expand Down
4 changes: 2 additions & 2 deletions examples/example-esbuild/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import './global.css';
import * as React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import * as stylex from '@stylexjs/stylex';
import { colors, fonts, sizes } from './globalTokens.stylex';

Expand Down Expand Up @@ -46,4 +46,4 @@ function App() {
);
}

ReactDOM.render(<App />, document.getElementById('root'));
createRoot(document.getElementById('root')).render(<App />);
Loading