Skip to content
Merged
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
5 changes: 1 addition & 4 deletions apps/playgrounds/bun-react/bun-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ type ProcessEnvAugmented = import("@arkenv/bun-plugin").ProcessEnvAugmented<
>;

declare namespace NodeJS {
interface ProcessEnv extends ProcessEnvAugmented {
BUN_PUBLIC_API_URL: string;
BUN_PUBLIC_DEBUG: boolean;
}
interface ProcessEnv extends ProcessEnvAugmented {}
}

declare module "*.svg" {
Expand Down
4 changes: 4 additions & 0 deletions arkenv.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@
"path": "examples/with-bun",
"name": " with-bun"
},
{
"path": "examples/with-bun-react",
"name": " with-bun-react"
},
{
"path": "examples/with-vite-react",
"name": " with-vite-react"
Expand Down
3 changes: 2 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ This directory contains a collection of example projects that demonstrate variou
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| [`basic`](https://github.com/yamcodes/arkenv/tree/main/examples/basic) | Minimal example of *using ArkEnv in a [Node.js](https://nodejs.org/) app* for learning the fundamentals. |
| [`with-bun`](https://github.com/yamcodes/arkenv/tree/main/examples/with-bun) | Minimal example of *using ArkEnv in a [Bun](https://bun.sh/) app*. |
| [`with-vite-react`](https://github.com/yamcodes/arkenv/tree/main/examples/with-vite-react) | Minimal example of *using ArkEnv in a [Vite](https://vite.dev/)+[React](https://react.dev/) app*.
| [`with-bun-react`](https://github.com/yamcodes/arkenv/tree/main/examples/with-bun-react) | Minimal example of *using ArkEnv in a [Bun+React](https://bun.com/docs/guides/ecosystem/react) full-stack app*. |
| [`with-vite-react`](https://github.com/yamcodes/arkenv/tree/main/examples/with-vite-react) | Minimal example of *using ArkEnv in a [Vite](https://vite.dev/)+[React](https://react.dev/) app*. |

## Contributing an example

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
description: Use Bun instead of Node.js, npm, pnpm, or vite.
globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
alwaysApply: false
---

Default to using Bun instead of Node.js.

- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
- Use `bun test` instead of `jest` or `vitest`
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
- Bun automatically loads .env, so don't use dotenv.

## APIs

- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
- `Bun.redis` for Redis. Don't use `ioredis`.
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
- `WebSocket` is built-in. Don't use `ws`.
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
- Bun.$`ls` instead of execa.

## Testing

Use `bun test` to run tests.

```ts#index.test.ts
import { test, expect } from "bun:test";

test("hello world", () => {
expect(1).toBe(1);
});
```

## Frontend

Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.

Server:

```ts#index.ts
import index from "./index.html"

Bun.serve({
routes: {
"/": index,
"/api/users/:id": {
GET: (req) => {
return new Response(JSON.stringify({ id: req.params.id }));
},
},
},
// optional websocket support
websocket: {
open: (ws) => {
ws.send("Hello, world!");
},
message: (ws, message) => {
ws.send(message);
},
close: (ws) => {
// handle close
}
},
development: {
hmr: true,
console: true,
}
})
```

HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.

```html#index.html
<html>
<body>
<h1>Hello, world!</h1>
<script type="module" src="./frontend.tsx"></script>
</body>
</html>
```

With the following `frontend.tsx`:

```tsx#frontend.tsx
import React from "react";

// import .css files directly and it works
import './index.css';

import { createRoot } from "react-dom/client";

const root = createRoot(document.body);

export default function Frontend() {
return <h1>Hello, world!</h1>;
}

root.render(<Frontend />);
```

Then, run index.ts

```sh
bun --hot ./index.ts
```

For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
3 changes: 3 additions & 0 deletions examples/with-bun-react/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BUN_PUBLIC_TEST=test-value
BUN_PUBLIC_BOOLEAN=true
PORT=3001
3 changes: 3 additions & 0 deletions examples/with-bun-react/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BUN_PUBLIC_TEST=test-value
BUN_PUBLIC_BOOLEAN=true
PORT=3000
34 changes: 34 additions & 0 deletions examples/with-bun-react/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules

# output
out
dist
*.tgz

# code coverage
coverage
*.lcov

# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# caches
.eslintcache
.cache
*.tsbuildinfo

# IntelliJ based IDEs
.idea

# Finder (MacOS) folder config
.DS_Store
51 changes: 51 additions & 0 deletions examples/with-bun-react/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# ArkEnv + Bun Plugin Example

This example demonstrates how to integrate [ArkEnv](https://github.com/arktypeio/arkenv) with the [Bun plugin](https://github.com/arktypeio/arkenv/tree/main/packages/bun-plugin) in a React application. It showcases how to define a type-safe environment schema, validate environment variables at build time, and safely expose public variables to the client.

## Environment

This project uses `src/env.ts` to define the environment schema using ArkType.

Variables prefixed with `BUN_PUBLIC_` are automatically exposed to the client-side code by the Bun plugin.

### Example Configuration

Create a `.env.development` or `.env.production` file with the following values:

```env
BUN_PUBLIC_TEST=test-value
BUN_PUBLIC_BOOLEAN=true
PORT=3000
```

See `src/env.ts` for the full schema definition.

## Getting Started

To install dependencies:

```bash
bun install
```

To start a development server:

```bash
bun dev
```

## Building for Production

To build the application for production:

```bash
bun run build
```

This runs the `build.ts` script, which utilizes the ArkEnv Bun plugin. The plugin performs **build-time validation** of your environment variables against the schema defined in `src/env.ts`. If any required variables are missing or invalid, the build will fail, ensuring your application is always deployed with a valid configuration.

To run the production server:

```bash
bun start
```
23 changes: 23 additions & 0 deletions examples/with-bun-react/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import arkenv from "@arkenv/bun-plugin";

const result = await Bun.build({
entrypoints: ["./src/index.html"],
outdir: "./dist",
sourcemap: "external",
target: "browser",
minify: true,
define: {
"process.env.NODE_ENV": JSON.stringify("production"),
},
plugins: [arkenv],
});

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

console.log("Build successful!");
24 changes: 24 additions & 0 deletions examples/with-bun-react/bun-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Import the Env schema type from env.ts
type ProcessEnvAugmented = import("@arkenv/bun-plugin").ProcessEnvAugmented<
typeof import("./src/env").default
>;

declare namespace NodeJS {
interface ProcessEnv extends ProcessEnvAugmented {}
}

declare module "*.svg" {
/**
* A path to the SVG file
*/
const path: `${string}.svg`;
export = path;
}

declare module "*.module.css" {
/**
* A record of class names to their corresponding CSS module classes
*/
const classes: { readonly [key: string]: string };
export = classes;
}
78 changes: 78 additions & 0 deletions examples/with-bun-react/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions examples/with-bun-react/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[serve.static]
env = "BUN_PUBLIC_*"
plugins = ["@arkenv/bun-plugin"]
24 changes: 24 additions & 0 deletions examples/with-bun-react/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "arkenv-example-with-bun-react",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "bun --hot src/index.ts",
"build": "bun build.ts",
"preview": "bun dist/index.html",
"start": "NODE_ENV=production bun src/index.ts"
},
"dependencies": {
"@arkenv/bun-plugin": "^0.0.1",
"arkenv": "^0.7.6",
"arktype": "^2.1.27",
"react": "^19",
"react-dom": "^19"
},
"devDependencies": {
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/bun": "latest"
}
}
Loading
Loading