Compare commits

...

17 Commits

Author SHA1 Message Date
Colin McDonnell
e77e078710 Update react example 2023-05-15 15:53:51 -07:00
Colin McDonnell
d348ec0668 Update readme 2023-05-15 15:02:17 -07:00
Colin McDonnell
85a518d778 Improve styling, add some components 2023-05-15 15:00:31 -07:00
Colin McDonnell
9f24220954 Update to Bun.build 2023-05-15 10:53:59 -07:00
Colin McDonnell
12d4d65032 WIP 2023-04-19 15:06:18 -07:00
Colin McDonnell
b285b12b8e Fix react-ssr 2023-04-19 13:37:14 -07:00
Colin McDonnell
9b988f840e Add SSR example that doesn't work 2023-04-19 13:11:12 -07:00
Colin McDonnell
43459484cb Add names and versions 2023-04-17 22:06:07 -07:00
Colin McDonnell
913fd5cbbe next to nextjs 2023-04-17 22:02:05 -07:00
Colin McDonnell
22bcb661a6 Update workflow 2023-04-17 21:52:19 -07:00
Colin McDonnell
4c74bc53fc Add remix template 2023-04-17 21:21:42 -07:00
Colin McDonnell
6cff67bf44 Add package.json scripts 2023-04-17 21:11:14 -07:00
Colin McDonnell
4e5a33ea2a Rename discord-interactions to discord-bot. Fix typo in apollo-server 2023-04-17 20:58:09 -07:00
Colin McDonnell
de314e94e7 Tweak react template 2023-04-17 20:03:02 -07:00
Colin McDonnell
a82fb8b7eb Get preact working 2023-04-17 19:58:52 -07:00
Colin McDonnell
fa9015cd14 WIP 2023-04-17 17:38:41 -07:00
Colin McDonnell
ddcd31802d WIP 2023-04-17 12:57:19 -07:00
161 changed files with 4170 additions and 31 deletions

View File

@@ -0,0 +1,33 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Publish bun-create templates
on:
push:
branches:
- "main"
paths:
- "templates/**"
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- uses: actions/setup-bun
- run: bun install
- run: bun run publish.ts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: "EndBug/add-and-commit@v9"
with:
default_author: github_actions

View File

@@ -1,5 +1,5 @@
<p align="center">
<a href="https://bun.sh"><img src="https://user-images.githubusercontent.com/709451/182802334-d9c42afe-f35d-4a7b-86ea-9985f73f20c3.png" alt="Logo" height=170></a>
<a href="https://bun.sh"><img src="https://user-images.githubusercontent.com/3084745/233164339-31089120-7451-41c5-8505-6082cbbfe06f.svg" alt="Logo" height=170></a>
</p>
<h1 align="center">Bun</h1>
@@ -48,7 +48,7 @@ bunx cowsay 'Hello, world!' # execute a package
Bun supports Linux (x64 & arm64) and macOS (x64 & Apple Silicon).
> **Linux users** — Kernel version 5.6 or higher is strongly recommended, but the minimum is 5.1.
>
>
> **Windows users** — Bun does not currently provide a native Windows build. We're working on this; progress can be tracked at [this issue](https://github.com/oven-sh/bun/issues/43). In the meantime, use one of the installation methods below for Windows Subsystem for Linux.
```sh
@@ -67,7 +67,6 @@ docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```
### Upgrade
To upgrade to the latest version of Bun, run:
@@ -127,7 +126,6 @@ bun upgrade --canary
- [DNS](https://bun.sh/docs/api/dns)
- [Node-API](https://bun.sh/docs/api/node-api)
## Contributing
Refer to the [Project > Development](https://bun.sh/docs/project/development) guide to start contributing to Bun.

View File

@@ -55,7 +55,7 @@ Running `bun create` performs the following steps:
The following official templates are available.
```bash
bun create next ./myapp
bun create nextjs ./myapp
bun create react ./myapp
bun create svelte-kit ./myapp
bun create elysia ./myapp

View File

@@ -1,7 +1,7 @@
To create a new Next.js app with bun:
```bash
$ bun create next ./app
$ bun create nextjs ./app
$ cd app
$ bun dev # start dev server
```

View File

@@ -55,7 +55,7 @@ Running `bun create` performs the following steps:
The following official templates are available.
```bash
bun create next ./myapp
bun create nextjs ./myapp
bun create react ./myapp
bun create svelte-kit ./myapp
bun create elysia ./myapp
@@ -156,8 +156,7 @@ Each of these can correspond to a string or array of strings. An array of comman
},
"bun-create": {
"preinstall": "echo 'Installing...'", // a single command
"postinstall": ["echo 'Done!'"], // an array of commands
"start": "bun run echo 'Hello world!'"
"postinstall": ["echo 'Done!'"] // an array of commands
}
}
```
@@ -246,7 +245,7 @@ ELSE IF local template
5. Auto-detect the npm client, preferring `pnpm`, `yarn` (v1), and lastly `npm`
6. Run any tasks defined in `"bun-create": { "preinstall" }` with the npm client
7. Run `${npmClient} install` unless `--no-install` is passed OR no dependencies are in package.json
8. Run any tasks defined in `"bun-create": { "preinstall" }` with the npm client
8. Run any tasks defined in `"bun-create": { "postinstall" }` with the npm client
9. Run `git init; git add -A .; git commit -am "Initial Commit";`
- Rename `gitignore` to `.gitignore`. NPM automatically removes `.gitignore` files from appearing in packages.

View File

@@ -4,7 +4,7 @@
If you see a message like this
> [1] 28447 killed bun create next ./test
> [1] 28447 killed bun create nextjs ./test
It most likely means youre running Buns x64 version on Apple Silicon. This happens if Bun is running via Rosetta. Rosetta is unable to emulate AVX2 instructions, which Bun indirectly uses.

View File

@@ -5,7 +5,7 @@ This package lets you use Next.js 12.2 with bun. This readme assumes you already
To start a new project:
```bash
bun create next --open
bun create nextjs --open
```
To use Next.js 12 with an existing project:

View File

@@ -1547,7 +1547,7 @@ pub const CreateCommand = struct {
Output.pretty(
\\
\\<d>Come hang out in bun's Discord: https://bun.sh/discord<r>
\\<d>Come hang out in Bun's Discord: https://bun.sh/discord<r>
\\
, .{});
@@ -1610,21 +1610,21 @@ pub const CreateCommand = struct {
}
if (is_nextjs) {
Output.pretty(
\\
\\<r><d>#<r> When dependencies change, run this to update node_modules.bun:
\\
\\ <b><cyan>bun bun --use next<r>
\\
, .{});
// Output.pretty(
// \\
// \\<r><d>#<r> When dependencies change, run this to update node_modules.bun:
// \\
// \\ <b><cyan>bun bun --use next<r>
// \\
// , .{});
} else if (is_create_react_app) {
Output.pretty(
\\
\\<r><d>#<r> When dependencies change, run this to update node_modules.bun:
\\
\\ <b><cyan>bun bun {s}<r>
\\
, .{create_react_app_entry_point_path});
// Output.pretty(
// \\
// \\<r><d>#<r> When dependencies change, run this to update node_modules.bun:
// \\
// \\ <b><cyan>bun bun {s}<r>
// \\
// , .{create_react_app_entry_point_path});
}
Output.pretty(
@@ -2117,18 +2117,18 @@ pub const CreateListExamplesCommand = struct {
Output.prettyln("Welcome to bun! Create a new project by pasting any of the following:\n\n", .{});
Output.flush();
Example.print(examples.items, null);
Example.print(examples.items, "./my-app");
Output.prettyln("<r><d>#<r> You can also paste a GitHub repository:\n\n <b>bun create <cyan>ahfarmer/calculator calc<r>\n\n", .{});
Output.prettyln("<r><d>#<r> To clone from a GitHub repository:\n\n <b>bun create <cyan>ahfarmer/calculator calc<r>\n\n", .{});
if (env_loader.map.get("HOME")) |homedir| {
Output.prettyln(
"<d>This command is completely optional. To add a new local template, create a folder in {s}/.bun-create/. To publish a new template, git clone https://github.com/oven-sh/bun, add a new folder to the \"examples\" folder, and submit a PR.<r>",
"<d>This command is completely optional. To add a new local template, create a folder in {s}/.bun-create/. To publish a new template, fork https://github.com/oven-sh/bun, add a new directory to the \"templates\" folder, and submit a PR.<r>",
.{homedir},
);
} else {
Output.prettyln(
"<d>This command is completely optional. To add a new local template, create a folder in $HOME/.bun-create/. To publish a new template, git clone https://github.com/oven-sh/bun, add a new folder to the \"examples\" folder, and submit a PR.<r>",
"<d>This command is completely optional. To add a new local template, create a folder in $HOME/.bun-create/. To publish a new template, fork https://github.com/oven-sh/bun, add a new directory to the \"templates\" folder, and submit a PR.<r>",
.{},
);
}

4
templates/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
templates/bun-examples-all
node_modules/
.idea/
bun.lockb

66
templates/README.md Normal file
View File

@@ -0,0 +1,66 @@
# Templates for `bun create`
This repo contains the templates for `bun create`.
## Usage
> Refer to the [Bun docs](https://bun.dev/docs/templates) for complete documentation of `bun create`.
To see a list of all official templates:
```bash
$ bun create
```
To scaffold a new project using a particular template:
```bash
$ bun create <template> <dir>
```
To scaffold a new project using a GitHub repo as a template:
```bash
$ bun create user/repo <dir>
```
## Creating a template
Fork this repo and add your template to the `templates` directory. The name of the directory will be the template name. For example, if you add a template named `my-template`, you can scaffold a new project using it with:
```bash
$ bun create my-template <dir>
```
In the `package.json`, set the `"name"` field to the pattern `@bun-examples/<name>`. The template code will be auto-published to `npm` using this name, where it will later be downloaded by `bun create`.
```json
{
"name": "@bun-examples/my-template"
}
```
The `package.json` can also contain some initialization logic in the `"bun-create"` field. This defines a set of hooks that `bun create` will run immediately after scaffolding a new project.
```json
{
// other fields
"bun-create": {
"preinstall": "echo 'Installing...'",
"postinstall": ["bun install"], // accepts array of commands,
"start": "bun run server.ts"
}
}
```
The `"start"` field is not executed, but it will be printed when a user scaffolds a new project using your template.
```bash
$ bun create my-template <dir>
# ...
Created my-template project successfully
# To get started, run:
cd <dir>
bun run server.ts # <- copied from the "start" field
```

View File

@@ -0,0 +1,19 @@
# Apollo Server with Bun runtime
## Getting Started
```sh
bun create apollo-server ./NAME_HERE
```
## Development
To start the development server run:
```bash
bun run start
```
Open http://localhost:4000/ with your browser to see the result.
### For more information
See Apollo's [getting started documentation](https://www.apollographql.com/docs/apollo-server/getting-started/)

View File

@@ -0,0 +1,2 @@
node_modules/
.DS_Store

View File

@@ -0,0 +1,16 @@
{
"version": "1.0.15",
"name": "@bun-examples/apollo-server",
"dependencies": {
"@apollo/server": "^4.3.2",
"graphql": "^16.6.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "bun run src/index.js"
},
"module": "src/index.js",
"bun-create": {
"start": "bun run src/index.js"
}
}

View File

@@ -0,0 +1,41 @@
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
const typeDefs = `#graphql
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
`;
const books = [
{
title: 'The Awakening',
author: 'Kate Chopin',
},
{
title: 'City of Glass',
author: 'Paul Auster',
},
];
const resolvers = {
Query: {
books: () => books,
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
await startStandaloneServer(server, {
listen: { port: 4000 },
});
console.log(`🚀 Server ready at: http://localhost:4000/graphql`);

42
templates/bun-bakery/.gitignore vendored Normal file
View File

@@ -0,0 +1,42 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,42 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun

View File

@@ -0,0 +1,10 @@
import { Router } from "@kapsonfire/bun-bakery";
const PORT = 3000;
new Router({
port: PORT,
assetsPath: import.meta.dir + "/assets/",
routesPath: import.meta.dir + "/routes/",
});
console.log(`Server running on port ${PORT}`);

View File

@@ -0,0 +1,10 @@
{
"version": "1.0.96",
"name": "@bun-examples/bun-bakery",
"dependencies": {
"@kapsonfire/bun-bakery": "^0.3.2"
},
"bun-create": {
"start": "bun run main.ts"
}
}

View File

@@ -0,0 +1,5 @@
import { Context } from "@kapsonfire/bun-bakery";
export async function GET(ctx: Context) {
ctx.sendHTML('<img src="/assets/bunbakery.png"><h1>Hello World!</h1>');
}

View File

@@ -0,0 +1,9 @@
{
"compilerOptions": {
"types": [
"bun-types"
],
"module": "esnext",
"moduleResolution": "Node"
}
}

View File

@@ -0,0 +1,52 @@
{
"name": "bun-examples-all",
"private": false,
"version": "0.0.1681763058946",
"description": "All bun-examples",
"examples": {
"@bun-examples/next": {
"version": "0.0.138",
"description": ""
},
"@bun-examples/svelte-kit": {
"version": "0.0.28",
"description": ""
},
"@bun-examples/websi": {
"version": "0.1.11",
"description": ""
},
"@bun-examples/elysia": {
"version": "1.0.31",
"description": ""
},
"@bun-examples/preact": {
"version": "0.0.6",
"description": ""
},
"@bun-examples/hono": {
"version": "1.0.90",
"description": ""
},
"@bun-examples/discord-interactions": {
"version": "0.0.101",
"description": ""
},
"@bun-examples/bun-bakery": {
"version": "1.0.96",
"description": ""
},
"@bun-examples/kingworld": {
"version": "1.0.31",
"description": ""
},
"@bun-examples/react": {
"version": "0.1.82",
"description": ""
},
"@bun-examples/apollo-server": {
"version": "1.0.15",
"description": ""
}
}
}

View File

@@ -0,0 +1,3 @@
DISCORD_APP_ID=
DISCORD_BOT_TOKEN=
DISCORD_PUBLIC_KEY=

88
templates/discord-bot/.gitignore vendored Normal file
View File

@@ -0,0 +1,88 @@
/data
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
#config file
config.json
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# TernJS port file
.tern-port
# pm2
.pm2
.pm2.bak

View File

@@ -0,0 +1,15 @@
# /create with Bun runtime
A [slash-create](https://npm.im/slash-create) template, using [Bun runtime](https://bun.sh).
## Getting Started
### Cloning the repo
```sh
bun create discord-interactions interactions-bot
```
### Development
To run this locally, rename `.env.example` to `.env` and fill in the variables, then run `bun run.js` to start a local dev environment and use something similar to [ngrok](https://ngrok.com/) or [cloudflare](https://www.cloudflare.com/) to tunnel it to a URL.

View File

@@ -0,0 +1,39 @@
import { join, extname } from 'path';
import { Creator } from 'slash-create';
import { readdirSync, lstatSync } from 'fs';
import { FetchRequestHandler } from './rest.js';
export { default as BunServer } from './server.js';
export class BunSlashCreator extends Creator {
constructor(...args) {
super(...args);
this.requestHandler = new FetchRequestHandler(this);
}
async registerCommandsIn(commandPath, customExtensions = []) {
const commands = [];
const extensions = ['.js', '.ts', '.mjs', '.cjs', ...customExtensions];
for (const path of find_files_with_extension(commandPath, extensions)) {
try {
commands.push(await import(path));
} catch (error) {
this.emit('error', new Error(`Failed to load command ${filePath}: ${e}`));
}
}
return this.registerCommands(commands, true);
}
}
function find_files_with_extension(path, extensions, names = []) {
for (const name of readdirSync(path)) {
const p = join(path, name);
const stat = lstatSync(p);
if (extensions.includes(extname(name))) names.push(p);
else if (stat.isDirectory()) find_files_with_extension(p, extensions, names);
}
return names;
}

View File

@@ -0,0 +1,48 @@
import { RequestHandler } from 'slash-create';
import { MultipartData } from 'slash-create/lib/util/multipartData.js';
export class FetchRequestHandler extends RequestHandler {
toString() {
return '[RequestHandler]';
}
async request(method, url, auth = true, body, file) {
const creator = this._creator;
const headers = {
'user-agent': this.userAgent,
'x-ratelimit-precision': 'millisecond',
};
if (auth) {
headers.authorization = creator.options.token;
if (!headers.authorization) throw new Error('No token was set in the SlashCreator.');
}
if (body) {
if (method !== 'GET' && method !== 'DELETE') {
body = JSON.stringify(body);
headers['content-type'] = 'application/json';
}
}
if (file) {
if (Array.isArray(file)) {}
else if (file.file) file = [file];
else throw new Error('Invalid file object.');
const form = new MultipartData();
headers['content-type'] = `multipart/form-data; boundary=${form.boundary}`;
for (const f of file) form.attach(f.name, f.file, f.name);
if (body) form.attach('payload_json', JSON.stringify(body));
body = Buffer.concat(form.finish());
}
const res = await fetch('https://discord.com' + this.baseURL + url, { body, method, headers });
if (res.ok) return res.json();
throw new Error(`${method} got ${res.status} - ${await res.text()}`);
}
}

View File

@@ -0,0 +1,79 @@
import { Server } from 'slash-create';
import { MultipartData } from 'slash-create/lib/util/multipartData.js';
export default class BunServer extends Server {
#server = null;
#handler = null;
isWebserver = true;
constructor() {
super({ alreadyListening: true });
}
createEndpoint(path, handler) {
this.#handler = handler;
}
stop() {
if (this.#server) this.#server.close();
else throw new Error('BunServer not started');
}
listen(port, options = {}) {
const getHandler = () => this.#handler;
this.#server = Bun.serve({
port,
...options,
async fetch(req) {
const handler = getHandler();
if (!handler) return new Response('Server has no handler.', { status: 503 });
if (req.method !== 'POST') return new Response('Server only supports POST requests.', { status: 405 });
const reqHeaders = Object.fromEntries(req.headers.entries());
const reqBody = await req.json();
return await new Promise(async (ok, err) => {
try {
await handler({
request: req,
body: reqBody,
response: null,
headers: reqHeaders,
}, response => {
let body = response.body;
const headers = new Headers();
if (response.headers) {
for (const key in response.headers) {
headers.set(key, response.headers[key]);
}
}
if ('string' !== typeof body) {
body = JSON.stringify(body);
headers.set('content-type', 'application/json');
}
if (response.files) {
const form = new MultipartData();
headers.set('content-type', `multipart/form-data; boundary=${form.boundary}`);
form.attach('payload_json', body);
for (const file of response.files) form.attach(file.name, file.file, file.name);
body = Buffer.concat(form.finish());
}
ok(new Response(body, { headers, status: response.status }));
});
} catch (error) {
err(error);
}
});
},
});
}
};

View File

@@ -0,0 +1,21 @@
import { SlashCommand, ApplicationCommandType } from 'slash-create';
export default class AvatarCommand extends SlashCommand {
constructor(creator) {
super(creator, {
// You must specify a type for context menu commands, but defaults
// to `CHAT_INPUT`, or regular slash commands.
type: ApplicationCommandType.USER,
name: 'Get Avatar URL',
});
this.filePath = __filename;
}
async run(ctx) {
// The target user can be accessed from here
// You can also use `ctx.targetMember` for member properties
const target = ctx.targetUser;
return `${target.username}'s Avatar: ${target.avatarURL}`;
}
}

View File

@@ -0,0 +1,21 @@
import { SlashCommand, CommandOptionType } from 'slash-create';
export default class HelloCommand extends SlashCommand {
constructor(creator) {
super(creator, {
name: 'hello',
description: 'Says hello to you.',
options: [{
type: CommandOptionType.STRING,
name: 'food',
description: 'What food do you like?'
}]
});
this.filePath = __filename;
}
async run(ctx) {
return ctx.options.food ? `You like ${ctx.options.food}? Nice!` : `Hello, ${ctx.user.username}!`;
}
}

View File

@@ -0,0 +1,51 @@
import { SlashCommand, ComponentType, TextInputStyle } from 'slash-create';
export default class ModalCommand extends SlashCommand {
constructor(creator) {
super(creator, {
name: 'modal',
description: 'Send a cool modal.'
});
this.filePath = __filename;
}
async run(ctx) {
// You can send a modal this way
// Keep in mind providing a callback is optional, but no callback requires the custom_id to be defined.
ctx.sendModal(
{
title: 'Example Modal',
components: [
{
type: ComponentType.ACTION_ROW,
components: [
{
type: ComponentType.TEXT_INPUT,
label: 'Text Input',
style: TextInputStyle.SHORT,
custom_id: 'text_input',
placeholder: 'Type something...'
}
]
},
{
type: ComponentType.ACTION_ROW,
components: [
{
type: ComponentType.TEXT_INPUT,
label: 'Long Text Input',
style: TextInputStyle.PARAGRAPH,
custom_id: 'long_text_input',
placeholder: 'Type something...'
}
]
}
]
},
(mctx) => {
mctx.send(`Your input: ${mctx.values.text_input}\nYour long input: ${mctx.values.long_text_input}`);
}
);
}
}

View File

@@ -0,0 +1,88 @@
/data
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
#config file
config.json
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# TernJS port file
.tern-port
# pm2
.pm2
.pm2.bak

View File

@@ -0,0 +1,10 @@
{
"version": "0.0.101",
"name": "@bun-examples/discord-bot",
"dependencies": {
"slash-create": "^5.9.0"
},
"bun-create": {
"start": "bun run run.js"
}
}

View File

@@ -0,0 +1,2 @@
Error.captureStackTrace = () => {};
Buffer.isBuffer = Buffer.isBuffer.bind(Buffer);

View File

@@ -0,0 +1,22 @@
// polyfill v8 and node (TODO: fix in bun)
import './polyfill.js';
import path from 'node:path';
import { BunServer, BunSlashCreator } from './bun_shim';
const client = new BunSlashCreator({
token: process.env.DISCORD_BOT_TOKEN,
publicKey: process.env.DISCORD_PUBLIC_KEY,
applicationID: process.env.DISCORD_APP_ID,
});
// client.on('debug', console.log);
client.on('error', console.error);
client.withServer(new BunServer());
await client.registerCommandsIn(path.join(__dirname, 'commands'));
client.syncCommands();
await client.server.listen(1337);
// client.server.stop(); // stop server

View File

@@ -0,0 +1,19 @@
# Elysia with Bun runtime
## Getting Started
To get started with this template, simply paste this command into your terminal:
```bash
bun create elysia ./elysia-example
```
## Development
To start the development server run:
```bash
bun run dev
```
Open http://localhost:3000/ with your browser to see the result.

View File

@@ -0,0 +1,42 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun

View File

@@ -0,0 +1,18 @@
{
"name": "@bun-examples/elysia",
"version": "1.0.31",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "bun run --hot src/index.ts"
},
"dependencies": {
"elysia": "latest"
},
"devDependencies": {
"bun-types": "latest"
},
"module": "src/index.js",
"bun-create": {
"start": "bun run src/index.ts"
}
}

View File

@@ -0,0 +1,5 @@
import { Elysia } from "elysia";
const app = new Elysia().get("/", () => "Hello Elysia").listen(3000);
console.log(`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`);

View File

@@ -0,0 +1,97 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ES2022", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
"types": [
"bun-types"
], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View File

@@ -0,0 +1,17 @@
{
"version": "1.0.90",
"name": "@bun-examples/hono",
"devDependencies": {
"bun-types": "latest"
},
"dependencies": {
"hono": "^2.2.5"
},
"scripts": {
"start": "bun run src/index.ts"
},
"module": "src/index.js",
"bun-create": {
"start": "bun run src/index.ts"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

21
templates/hono/readme.md Normal file
View File

@@ -0,0 +1,21 @@
# Hono with Bun runtime
## Getting Started
### Cloning the repo
```sh
bun create hono ./NAME_HERE
```
### Development
```
bun run start
```
Open http://localhost:3000 with your browser to see the result.
### For more information
See <https://honojs.dev/>

View File

@@ -0,0 +1,19 @@
import { Hono } from "hono";
import { serveStatic } from 'hono/serve-static.bun';
const port = parseInt(process.env.PORT) || 3000;
const app = new Hono();
app.use('/favicon.ico', serveStatic({ path: './public/favicon.ico' }));
app.get("/", (c) => {
return c.json({ message: "Hello World!" });
});
console.log(`Running at http://localhost:${port}`);
export default {
port,
fetch: app.fetch
};

View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "node",
// "bun-types" is the important part
"types": ["bun-types"]
}
}

View File

@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}

36
templates/nextjs/.gitignore vendored Normal file
View File

@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

@@ -0,0 +1,28 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`bun create`](https://bun.sh/docs/templates). It is a modified version of [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
bun run dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

View File

@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig

View File

@@ -0,0 +1,27 @@
{
"name": "@bun-examples/nextjs",
"version": "0.0.1",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@types/node": "18.15.11",
"@types/react": "18.0.37",
"@types/react-dom": "18.0.11",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
"next": "13.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "5.0.4"
},
"bun-create": {
"postinstall": [
"echo 'Important note! Next.js uses Node.js under the hood. The build performance and\nstartup times may feel slow compared to frameworks that take advantage of Bun.\n'"
],
"start": "bun run dev"
}
}

View File

@@ -0,0 +1,6 @@
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}

View File

@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}

View File

@@ -0,0 +1,13 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
res.status(200).json({ name: 'John Doe' })
}

View File

@@ -0,0 +1,101 @@
import Head from "next/head";
import Image from "next/image";
import { Inter } from "next/font/google";
import styles from "@/styles/Home.module.css";
const inter = Inter({ subsets: ["latin"] });
export default function Home() {
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div className={styles.description}>
<p>
Get started by editing&nbsp;
<code className={styles.code}>pages/index.tsx</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{" "}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className={styles.vercelLogo}
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className={styles.center}>
<Image className={styles.logo} src="/next.svg" alt="Next.js Logo" width={180} height={37} priority />
<div className={styles.thirteen}>
<Image src="/thirteen.svg" alt="13" width={40} height={31} priority />
</div>
</div>
<div className={styles.grid}>
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2 className={inter.className}>
Docs <span>-&gt;</span>
</h2>
<p className={inter.className}>Find in-depth information about Next.js features and&nbsp;API.</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2 className={inter.className}>
Learn <span>-&gt;</span>
</h2>
<p className={inter.className}>Learn about Next.js in an interactive course with&nbsp;quizzes!</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2 className={inter.className}>
Templates <span>-&gt;</span>
</h2>
<p className={inter.className}>Discover and deploy boilerplate example Next.js&nbsp;projects.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2 className={inter.className}>
Deploy <span>-&gt;</span>
</h2>
<p className={inter.className}>Instantly deploy your Next.js site to a shareable URL with&nbsp;Vercel.</p>
</a>
</div>
</main>
</>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="31" fill="none"><g opacity=".9"><path fill="url(#a)" d="M13 .4v29.3H7V6.3h-.2L0 10.5V5L7.2.4H13Z"/><path fill="url(#b)" d="M28.8 30.1c-2.2 0-4-.3-5.7-1-1.7-.8-3-1.8-4-3.1a7.7 7.7 0 0 1-1.4-4.6h6.2c0 .8.3 1.4.7 2 .4.5 1 .9 1.7 1.2.7.3 1.6.4 2.5.4 1 0 1.7-.2 2.5-.5.7-.3 1.3-.8 1.7-1.4.4-.6.6-1.2.6-2s-.2-1.5-.7-2.1c-.4-.6-1-1-1.8-1.4-.8-.4-1.8-.5-2.9-.5h-2.7v-4.6h2.7a6 6 0 0 0 2.5-.5 4 4 0 0 0 1.7-1.3c.4-.6.6-1.3.6-2a3.5 3.5 0 0 0-2-3.3 5.6 5.6 0 0 0-4.5 0 4 4 0 0 0-1.7 1.2c-.4.6-.6 1.2-.6 2h-6c0-1.7.6-3.2 1.5-4.5 1-1.3 2.2-2.3 3.8-3C25 .4 26.8 0 28.8 0s3.8.4 5.3 1.1c1.5.7 2.7 1.7 3.6 3a7.2 7.2 0 0 1 1.2 4.2c0 1.6-.5 3-1.5 4a7 7 0 0 1-4 2.2v.2c2.2.3 3.8 1 5 2.2a6.4 6.4 0 0 1 1.6 4.6c0 1.7-.5 3.1-1.4 4.4a9.7 9.7 0 0 1-4 3.1c-1.7.8-3.7 1.1-5.8 1.1Z"/></g><defs><linearGradient id="a" x1="20" x2="20" y1="0" y2="30.1" gradientUnits="userSpaceOnUse"><stop/><stop offset="1" stop-color="#3D3D3D"/></linearGradient><linearGradient id="b" x1="20" x2="20" y1="0" y2="30.1" gradientUnits="userSpaceOnUse"><stop/><stop offset="1" stop-color="#3D3D3D"/></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

View File

@@ -0,0 +1,278 @@
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 6rem;
min-height: 100vh;
}
.description {
display: inherit;
justify-content: inherit;
align-items: inherit;
font-size: 0.85rem;
max-width: var(--max-width);
width: 100%;
z-index: 2;
font-family: var(--font-mono);
}
.description a {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
}
.description p {
position: relative;
margin: 0;
padding: 1rem;
background-color: rgba(var(--callout-rgb), 0.5);
border: 1px solid rgba(var(--callout-border-rgb), 0.3);
border-radius: var(--border-radius);
}
.code {
font-weight: 700;
font-family: var(--font-mono);
}
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(25%, auto));
width: var(--max-width);
max-width: 100%;
}
.card {
padding: 1rem 1.2rem;
border-radius: var(--border-radius);
background: rgba(var(--card-rgb), 0);
border: 1px solid rgba(var(--card-border-rgb), 0);
transition: background 200ms, border 200ms;
}
.card span {
display: inline-block;
transition: transform 200ms;
}
.card h2 {
font-weight: 600;
margin-bottom: 0.7rem;
}
.card p {
margin: 0;
opacity: 0.6;
font-size: 0.9rem;
line-height: 1.5;
max-width: 30ch;
}
.center {
display: flex;
justify-content: center;
align-items: center;
position: relative;
padding: 4rem 0;
}
.center::before {
background: var(--secondary-glow);
border-radius: 50%;
width: 480px;
height: 360px;
margin-left: -400px;
}
.center::after {
background: var(--primary-glow);
width: 240px;
height: 180px;
z-index: -1;
}
.center::before,
.center::after {
content: '';
left: 50%;
position: absolute;
filter: blur(45px);
transform: translateZ(0);
}
.logo,
.thirteen {
position: relative;
}
.thirteen {
display: flex;
justify-content: center;
align-items: center;
width: 75px;
height: 75px;
padding: 25px 10px;
margin-left: 16px;
transform: translateZ(0);
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: 0px 2px 8px -1px #0000001a;
}
.thirteen::before,
.thirteen::after {
content: '';
position: absolute;
z-index: -1;
}
/* Conic Gradient Animation */
.thirteen::before {
animation: 6s rotate linear infinite;
width: 200%;
height: 200%;
background: var(--tile-border);
}
/* Inner Square */
.thirteen::after {
inset: 0;
padding: 1px;
border-radius: var(--border-radius);
background: linear-gradient(
to bottom right,
rgba(var(--tile-start-rgb), 1),
rgba(var(--tile-end-rgb), 1)
);
background-clip: content-box;
}
/* Enable hover only on non-touch devices */
@media (hover: hover) and (pointer: fine) {
.card:hover {
background: rgba(var(--card-rgb), 0.1);
border: 1px solid rgba(var(--card-border-rgb), 0.15);
}
.card:hover span {
transform: translateX(4px);
}
}
@media (prefers-reduced-motion) {
.thirteen::before {
animation: none;
}
.card:hover span {
transform: none;
}
}
/* Mobile */
@media (max-width: 700px) {
.content {
padding: 4rem;
}
.grid {
grid-template-columns: 1fr;
margin-bottom: 120px;
max-width: 320px;
text-align: center;
}
.card {
padding: 1rem 2.5rem;
}
.card h2 {
margin-bottom: 0.5rem;
}
.center {
padding: 8rem 0 6rem;
}
.center::before {
transform: none;
height: 300px;
}
.description {
font-size: 0.8rem;
}
.description a {
padding: 1rem;
}
.description p,
.description div {
display: flex;
justify-content: center;
position: fixed;
width: 100%;
}
.description p {
align-items: center;
inset: 0 0 auto;
padding: 2rem 1rem 1.4rem;
border-radius: 0;
border: none;
border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
background: linear-gradient(
to bottom,
rgba(var(--background-start-rgb), 1),
rgba(var(--callout-rgb), 0.5)
);
background-clip: padding-box;
backdrop-filter: blur(24px);
}
.description div {
align-items: flex-end;
pointer-events: none;
inset: auto 0 0;
padding: 2rem;
height: 200px;
background: linear-gradient(
to bottom,
transparent 0%,
rgb(var(--background-end-rgb)) 40%
);
z-index: 1;
}
}
/* Tablet and Smaller Desktop */
@media (min-width: 701px) and (max-width: 1120px) {
.grid {
grid-template-columns: repeat(2, 50%);
}
}
@media (prefers-color-scheme: dark) {
.vercelLogo {
filter: invert(1);
}
.logo,
.thirteen img {
filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
}
}
@keyframes rotate {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}

View File

@@ -0,0 +1,107 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro',
'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
--primary-glow: conic-gradient(
from 180deg at 50% 50%,
#16abff33 0deg,
#0885ff33 55deg,
#54d6ff33 120deg,
#0071ff33 160deg,
transparent 360deg
);
--secondary-glow: radial-gradient(
rgba(255, 255, 255, 1),
rgba(255, 255, 255, 0)
);
--tile-start-rgb: 239, 245, 249;
--tile-end-rgb: 228, 232, 233;
--tile-border: conic-gradient(
#00000080,
#00000040,
#00000030,
#00000020,
#00000010,
#00000010,
#00000080
);
--callout-rgb: 238, 240, 241;
--callout-border-rgb: 172, 175, 176;
--card-rgb: 180, 185, 188;
--card-border-rgb: 131, 134, 135;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
--secondary-glow: linear-gradient(
to bottom right,
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0.3)
);
--tile-start-rgb: 2, 13, 46;
--tile-end-rgb: 2, 5, 19;
--tile-border: conic-gradient(
#ffffff80,
#ffffff40,
#ffffff30,
#ffffff20,
#ffffff10,
#ffffff10,
#ffffff80
);
--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
--card-rgb: 100, 100, 100;
--card-border-rgb: 200, 200, 200;
}
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a {
color: inherit;
text-decoration: none;
}
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}

View File

@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

71
templates/package-lock.json generated Normal file
View File

@@ -0,0 +1,71 @@
{
"name": "create-templates",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"devDependencies": {
"semver": "^7.3.8"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
},
"dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
}

10
templates/package.json Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "@bun-examples/websi",
"version": "0.0.1",
"devDependencies": {
"semver": "^7.3.8",
"bun-types": "canary"
},
"module": "index.ts",
"type": "module"
}

5
templates/preact/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
node_modules
/build
/*.log
.build

View File

@@ -0,0 +1,32 @@
# Preact with Bun runtime
This is a Preact project bootstrapped with [bun](https://bun.sh/).
## Getting Started
### Cloning the repo
```sh
bun create preact ./preact-bun-app
```
### Development
First, run the development server.
```
bun dev
```
Open http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying `src/app.jsx`. The page auto-updates as you edit the file.
## Learn More
To learn more about Preact.js, take a look at the following resources:
- [Preact.js Documentation](https://preactjs.com/guide/v10/getting-started) - learn about Preact.js features.
- [Learn Preact.js](https://preactjs.com/tutorial/) - an interactive Preact.js tutorial.
You can check out the [Preact.js GitHub repository](https://github.com/preactjs/preact) - your feedback and contributions are welcome!

44
templates/preact/dev.tsx Normal file
View File

@@ -0,0 +1,44 @@
import * as path from "path";
import { statSync } from "fs";
import type { ServeOptions } from "bun";
const projectRoot = import.meta.dir;
const PUBLIC_DIR = path.resolve(projectRoot, "public");
const BUILD_DIR = path.resolve(projectRoot, ".build");
const PORT = process.env.PORT || 3000;
function serveFromDir(config: { directory: string; path: string }): Response | null {
let basePath = path.join(config.directory, config.path);
const suffixes = ["", ".html", "index.html"];
for (const suffix of suffixes) {
try {
const pathWithSuffix = path.join(basePath, suffix);
const stat = statSync(pathWithSuffix);
if (stat && stat.isFile()) {
return new Response(Bun.file(pathWithSuffix));
}
} catch (err) {}
}
return null;
}
export default {
port: PORT,
fetch(req) {
let reqPath = new URL(req.url).pathname;
console.log(req.method, reqPath);
const publicResponse = serveFromDir({ directory: PUBLIC_DIR, path: reqPath });
if (publicResponse) return publicResponse;
const buildResponse = serveFromDir({ directory: BUILD_DIR, path: reqPath });
if (buildResponse) return buildResponse;
return new Response("Not found", {
status: 404,
});
},
} satisfies ServeOptions;

View File

@@ -0,0 +1,3 @@
node_modules
/build
/*.log

View File

@@ -0,0 +1 @@
console.log("Hello via Bun!");

View File

@@ -0,0 +1,19 @@
{
"name": "@bun-examples/preact",
"version": "0.0.6",
"type": "module",
"devDependencies": {
"bun-types": "canary"
},
"dependencies": {
"preact": "^10.13.0"
},
"scripts": {
"predev": "NODE_ENV=development bun build ./src/index.jsx --outfile ./.build/bundle.js",
"dev": "bun --watch run dev.tsx"
},
"bun-create": {
"start": "bun run dev"
},
"module": "index.ts"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,105 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
justify-content: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.h-full {
min-height: 100vh;
}
.column-center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.row {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.logo {
height: 6em;
padding: 1.5em;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.preact:hover {
filter: drop-shadow(0 0 2em #673ab8aa);
}
.read-the-docs {
color: #888;
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bun + Preact</title>
<link rel="stylesheet" href="/index.css" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="/bundle.js" async type="module"></script>
</body>
</html>

View File

@@ -0,0 +1 @@
<svg id="Bun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 70"><title>Bun Logo</title><path id="Shadow" d="M71.09,20.74c-.16-.17-.33-.34-.5-.5s-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5A26.46,26.46,0,0,1,75.5,35.7c0,16.57-16.82,30.05-37.5,30.05-11.58,0-21.94-4.23-28.83-10.86l.5.5.5.5.5.5.5.5.5.5.5.5.5.5C19.55,65.3,30.14,69.75,42,69.75c20.68,0,37.5-13.48,37.5-30C79.5,32.69,76.46,26,71.09,20.74Z"/><g id="Body"><path id="Background" d="M73,35.7c0,15.21-15.67,27.54-35,27.54S3,50.91,3,35.7C3,26.27,9,17.94,18.22,13S33.18,3,38,3s8.94,4.13,19.78,10C67,17.94,73,26.27,73,35.7Z" style="fill:#fbf0df"/><path id="Bottom_Shadow" data-name="Bottom Shadow" d="M73,35.7a21.67,21.67,0,0,0-.8-5.78c-2.73,33.3-43.35,34.9-59.32,24.94A40,40,0,0,0,38,63.24C57.3,63.24,73,50.89,73,35.7Z" style="fill:#f6dece"/><path id="Light_Shine" data-name="Light Shine" d="M24.53,11.17C29,8.49,34.94,3.46,40.78,3.45A9.29,9.29,0,0,0,38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7c0,.4,0,.8,0,1.19C9.06,15.48,20.07,13.85,24.53,11.17Z" style="fill:#fffefc"/><path id="Top" d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z" style="fill:#ccbea7;fill-rule:evenodd"/><path id="Outline" d="M38,65.75C17.32,65.75.5,52.27.5,35.7c0-10,6.18-19.33,16.53-24.92,3-1.6,5.57-3.21,7.86-4.62,1.26-.78,2.45-1.51,3.6-2.19C32,1.89,35,.5,38,.5s5.62,1.2,8.9,3.14c1,.57,2,1.19,3.07,1.87,2.49,1.54,5.3,3.28,9,5.27C69.32,16.37,75.5,25.69,75.5,35.7,75.5,52.27,58.68,65.75,38,65.75ZM38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7,3,50.89,18.7,63.25,38,63.25S73,50.89,73,35.7C73,26.62,67.31,18.13,57.78,13,54,11,51.05,9.12,48.66,7.64c-1.09-.67-2.09-1.29-3-1.84C42.63,4,40.42,3,38,3Z"/></g><g id="Mouth"><g id="Background-2" data-name="Background"><path d="M45.05,43a8.93,8.93,0,0,1-2.92,4.71,6.81,6.81,0,0,1-4,1.88A6.84,6.84,0,0,1,34,47.71,8.93,8.93,0,0,1,31.12,43a.72.72,0,0,1,.8-.81H44.26A.72.72,0,0,1,45.05,43Z" style="fill:#b71422"/></g><g id="Tongue"><path id="Background-3" data-name="Background" d="M34,47.79a6.91,6.91,0,0,0,4.12,1.9,6.91,6.91,0,0,0,4.11-1.9,10.63,10.63,0,0,0,1-1.07,6.83,6.83,0,0,0-4.9-2.31,6.15,6.15,0,0,0-5,2.78C33.56,47.4,33.76,47.6,34,47.79Z" style="fill:#ff6164"/><path id="Outline-2" data-name="Outline" d="M34.16,47a5.36,5.36,0,0,1,4.19-2.08,6,6,0,0,1,4,1.69c.23-.25.45-.51.66-.77a7,7,0,0,0-4.71-1.93,6.36,6.36,0,0,0-4.89,2.36A9.53,9.53,0,0,0,34.16,47Z"/></g><path id="Outline-3" data-name="Outline" d="M38.09,50.19a7.42,7.42,0,0,1-4.45-2,9.52,9.52,0,0,1-3.11-5.05,1.2,1.2,0,0,1,.26-1,1.41,1.41,0,0,1,1.13-.51H44.26a1.44,1.44,0,0,1,1.13.51,1.19,1.19,0,0,1,.25,1h0a9.52,9.52,0,0,1-3.11,5.05A7.42,7.42,0,0,1,38.09,50.19Zm-6.17-7.4c-.16,0-.2.07-.21.09a8.29,8.29,0,0,0,2.73,4.37A6.23,6.23,0,0,0,38.09,49a6.28,6.28,0,0,0,3.65-1.73,8.3,8.3,0,0,0,2.72-4.37.21.21,0,0,0-.2-.09Z"/></g><g id="Face"><ellipse id="Right_Blush" data-name="Right Blush" cx="53.22" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"/><ellipse id="Left_Bluch" data-name="Left Bluch" cx="22.95" cy="40.18" rx="5.85" ry="3.44" style="fill:#febbd0"/><path id="Eyes" d="M25.7,38.8a5.51,5.51,0,1,0-5.5-5.51A5.51,5.51,0,0,0,25.7,38.8Zm24.77,0A5.51,5.51,0,1,0,45,33.29,5.5,5.5,0,0,0,50.47,38.8Z" style="fill-rule:evenodd"/><path id="Iris" d="M24,33.64a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,24,33.64Zm24.77,0a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,48.75,33.64Z" style="fill:#fff;fill-rule:evenodd"/></g></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="27.68" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 296"><path fill="#673AB8" d="m128 0l128 73.9v147.8l-128 73.9L0 221.7V73.9z"></path><path fill="#FFF" d="M34.865 220.478c17.016 21.78 71.095 5.185 122.15-34.704c51.055-39.888 80.24-88.345 63.224-110.126c-17.017-21.78-71.095-5.184-122.15 34.704c-51.055 39.89-80.24 88.346-63.224 110.126Zm7.27-5.68c-5.644-7.222-3.178-21.402 7.573-39.253c11.322-18.797 30.541-39.548 54.06-57.923c23.52-18.375 48.303-32.004 69.281-38.442c19.922-6.113 34.277-5.075 39.92 2.148c5.644 7.223 3.178 21.403-7.573 39.254c-11.322 18.797-30.541 39.547-54.06 57.923c-23.52 18.375-48.304 32.004-69.281 38.441c-19.922 6.114-34.277 5.076-39.92-2.147Z"></path><path fill="#FFF" d="M220.239 220.478c17.017-21.78-12.169-70.237-63.224-110.126C105.96 70.464 51.88 53.868 34.865 75.648c-17.017 21.78 12.169 70.238 63.224 110.126c51.055 39.889 105.133 56.485 122.15 34.704Zm-7.27-5.68c-5.643 7.224-19.998 8.262-39.92 2.148c-20.978-6.437-45.761-20.066-69.28-38.441c-23.52-18.376-42.74-39.126-54.06-57.923c-10.752-17.851-13.218-32.03-7.575-39.254c5.644-7.223 19.999-8.261 39.92-2.148c20.978 6.438 45.762 20.067 69.281 38.442c23.52 18.375 42.739 39.126 54.06 57.923c10.752 17.85 13.218 32.03 7.574 39.254Z"></path><path fill="#FFF" d="M127.552 167.667c10.827 0 19.603-8.777 19.603-19.604c0-10.826-8.776-19.603-19.603-19.603c-10.827 0-19.604 8.777-19.604 19.603c0 10.827 8.777 19.604 19.604 19.604Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,23 @@
import { useState } from "preact/hooks";
export function App() {
const [count, setCount] = useState(0);
return (
<div class="h-full column-center">
<div class="row">
<a href="https://bun.sh" target="_blank">
<img src="/logo.svg" class="logo" alt="Bun logo" />
</a>
<a href="https://preactjs.com" target="_blank">
<img src={"/preact.svg"} class="logo preact" alt="Preact logo" />
</a>
</div>
<h1>Bun + Preact</h1>
<button onClick={() => setCount(count => count + 1)}>count is {count}</button>
<p class="read-the-docs">Click on the Bun and Preact logos to learn more</p>
</div>
);
}

View File

@@ -0,0 +1,4 @@
import { render } from "preact";
import { App } from "./app";
render(<App />, document.getElementById("root"));

View File

@@ -0,0 +1,33 @@
{
"compilerOptions": {
"lib": [
"ESNext"
],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"types": [
"bun-types" // add Bun global
],
// Preact configuration
"jsx": "react-jsx",
"jsxImportSource": "preact-",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"baseUrl": ".",
"paths": {
"react": [
"node_modules/preact/compat"
],
"preact-jsx-dev-runtime": [
"node_modules/preact/jsx-runtime"
],
},
}
}

139
templates/publish.ts Normal file
View File

@@ -0,0 +1,139 @@
import * as fs from "fs";
const path = require("path");
const { execSync } = require("child_process");
const exec = (cmd: string, opts: { cwd?: string; env?: object } = {}) => {
console.log("$", cmd);
return execSync(cmd, {
...opts,
env: { CI: "true", ...process.env, ...(opts.env || {}) },
});
};
const DRY_RUN = !!process.env.DRY_RUN;
var count = 0;
const examplesFolderEntries = fs.readdirSync(path.join(process.cwd(), "."), { withFileTypes: true });
const packageNames: [string, { version: string; description: string }][] = [];
for (let folder of examplesFolderEntries) {
if (!folder.isDirectory()) continue;
const absolute = path.resolve(process.cwd(), ".", folder.name);
let packageJSONText;
try {
packageJSONText = fs.readFileSync(path.join(absolute, "package.json"), "utf8");
} catch {
continue;
}
let packageJSON = JSON.parse(packageJSONText);
if (!packageJSON.name) continue;
if (!packageJSON.name.startsWith("@bun-examples")) continue;
var version = "0.0.1";
try {
const _versions = exec(`npm view ${packageJSON.name} versions --json`).toString().trim();
if (_versions.length > 0) {
const versionsArray = JSON.parse(_versions);
version = versionsArray[versionsArray.length - 1];
}
} catch (exception) {
console.error(exception);
}
var retryCount = 5;
// Never commit lockfiles
try {
fs.rmSync(path.join(absolute, "package-lock.json"));
} catch (exception) {}
try {
fs.rmSync(path.join(absolute, "yarn.lock"));
} catch (exception) {}
try {
fs.rmSync(path.join(absolute, "pnpm-lock.yaml"));
} catch (exception) {}
try {
fs.copyFileSync(path.join(absolute, ".gitignore"), path.join(absolute, "gitignore"));
} catch (exception) {}
restart: while (retryCount-- > 0) {
// no longer necessary with `npm version patch` call
// packageJSON.version = require("semver").inc(packageJSON.version, "patch");
if ("private" in packageJSON) delete packageJSON.private;
if ("license" in packageJSON) delete packageJSON.license;
if ("main" in packageJSON && !("module" in packageJSON)) {
packageJSON.module = packageJSON.main;
delete packageJSON.main;
}
fs.writeFileSync(path.join(absolute, "package.json"), JSON.stringify(packageJSON, null, 2));
try {
exec(`npm version patch --force --no-commit-hooks --no-git-tag-version`, {
cwd: absolute,
});
packageJSON = JSON.parse(fs.readFileSync(path.join(absolute, "package.json"), "utf8"));
version = packageJSON.version;
} catch (e: any) {
if (e.code !== "E404") {
throw e;
}
}
try {
exec(`npm publish ${DRY_RUN ? "--dry-run" : ""} --access public --registry https://registry.npmjs.org/`, {
cwd: absolute,
});
packageNames.push([
packageJSON.name,
{
version: packageJSON.version,
description: packageJSON.description || "",
},
]);
count++;
break;
} catch (exception) {
continue restart;
}
}
}
if (packageNames.length > 0) {
const packageJSON = {
name: "bun-examples-all",
private: false,
version: `0.0.${Date.now()}`,
description: "All bun-examples",
examples: Object.fromEntries(packageNames),
};
const dir = path.join(process.cwd(), "./bun-examples-all");
try {
fs.rmSync(dir, {
recursive: true,
force: true,
});
} catch (exception) {}
try {
fs.mkdirSync(dir, {
recursive: true,
});
} catch (exception) {}
fs.writeFileSync(path.join(dir, "package.json"), JSON.stringify(packageJSON, null, 2));
exec(`npm publish ${DRY_RUN ? "--dry-run" : ""} --access public --registry https://registry.npmjs.org/`, {
cwd: dir,
});
}
console.log(`Published ${count} packages`);

34
templates/react-ssr/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.build

View File

@@ -0,0 +1,31 @@
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -0,0 +1,27 @@
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<div style={{ display: "flex" }}>
<button
style={{ cursor: "pointer", border: "none", borderRadius: "4px", width: "20px" }}
onClick={() => setCount(count - 1)}
>
-
</button>
<span style={{ paddingLeft: "10px", paddingRight: "10px", fontSize: "14pt", fontFamily: "monospace" }}>
{count}
</span>
<button
style={{ cursor: "pointer", border: "none", borderRadius: "4px", width: "20px" }}
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
);
}

View File

@@ -0,0 +1,43 @@
import React, { useState } from "react";
{
/* <div style={{display: "flex", flexDirection: "column"}}>
<h1>{props.title}</h1>
<Counter />
<p>
<a href="/">Home</a>
</p>
<p>
<a href="/settings">Settings</a>
</p>
</div> */
}
export function Layout(props: { title: string; children: React.ReactNode }) {
return (
<html>
<head>
<meta charSet="utf-8" />
<link rel="icon" href="favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
<title>{props.title}</title>
<link rel="stylesheet" href="/index.css" />
</head>
<body>
<div className="App" role="main">
<article className="App-article">
<img src={"/bunlogo.svg"} className="App-logo" alt="logo" />
<div style={{ height: "30px" }}></div>
<h3>{props.title}</h3>
<div style={{ height: "30px" }}></div>
{props.children}
</article>
</div>
</body>
</html>
);
}

View File

@@ -0,0 +1,21 @@
# React SSR
This is a project demonstrating how to build a simple Bun app with server-side rendering React + client-side hydration.
## Getting started
```sh
bun create react-ssr
bun install
bun run dev
```
This starts the development server in watch mode. Open http://localhost:3000 in your browser to see the result.
## Learn more
The following files are the most important:
- `dev.tsx`: Generates a browser build of all `pages` using `Bun.build`, then starts a dev server that handles incoming requests. For paths like `/` and `/settings`, the server will render the appropriate page in `pages` to static HTML and return the result. The returned HTML includes a `<script>` tag that imports a bundled version of `hydrate.tsx`.
- `hydrate.tsx`: A script that hydrates the static HTML returned by the server.
- `pages/*.tsx`: A set of pages. Incoming requests are resolved against this directory using Next.js-style routing.

View File

@@ -0,0 +1,79 @@
import * as path from "path";
import { statSync } from "fs";
import type { ServeOptions } from "bun";
import { renderToReadableStream, renderToString } from "react-dom/server";
const PROJECT_ROOT = import.meta.dir;
const PUBLIC_DIR = path.resolve(PROJECT_ROOT, "public");
const BUILD_DIR = path.resolve(PROJECT_ROOT, ".build");
const srcRouter = new Bun.FileSystemRouter({
dir: "./pages",
style: "nextjs",
});
await Bun.build({
entrypoints: [import.meta.dir + "/hydrate.tsx", ...Object.values(srcRouter.routes)],
outdir: BUILD_DIR,
target: "browser",
splitting: true,
});
const buildRouter = new Bun.FileSystemRouter({
dir: BUILD_DIR,
style: "nextjs",
});
function serveFromDir(config: { directory: string; path: string }): Response | null {
let basePath = path.join(config.directory, config.path);
const suffixes = ["", ".html", "index.html"];
for (const suffix of suffixes) {
try {
const pathWithSuffix = path.join(basePath, suffix);
const stat = statSync(pathWithSuffix);
if (stat && stat.isFile()) {
return new Response(Bun.file(pathWithSuffix));
}
} catch (err) {}
}
return null;
}
export default {
async fetch(request) {
const match = srcRouter.match(request);
if (match) {
const builtMatch = buildRouter.match(request);
if (!builtMatch) {
return new Response("Unknown error", { status: 500 });
}
const Component = await import(match.filePath);
const stream = await renderToReadableStream(<Component.default />, {
bootstrapScriptContent: `globalThis.PATH_TO_PAGE = "/${builtMatch.src}";`,
bootstrapModules: ["/hydrate.js"],
});
return new Response(stream, {
"headers": { "Content-Type": "text/html; charset=utf-8" },
});
}
let reqPath = new URL(request.url).pathname;
console.log(request.method, reqPath);
if (reqPath === "/") reqPath = "/index.html";
// check public
const publicResponse = serveFromDir({ directory: PUBLIC_DIR, path: reqPath });
if (publicResponse) return publicResponse;
// check /.build
const buildResponse = serveFromDir({ directory: BUILD_DIR, path: reqPath });
if (buildResponse) return buildResponse;
return new Response("File not found", {
status: 404,
});
},
} satisfies ServeOptions;

View File

@@ -0,0 +1,32 @@
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -0,0 +1,4 @@
import { hydrateRoot } from "react-dom/client";
const { default: App } = await import(globalThis.PATH_TO_PAGE);
hydrateRoot(document, <App />);

View File

@@ -0,0 +1,23 @@
{
"name": "@bun-examples/react-ssr",
"version": "0.1.82",
"dependencies": {
"bun-types": "canary",
"react": "next",
"react-dom": "next",
"web-vitals": "^3.0.3"
},
"devDependencies": {
"@types/react": "^18.0.37",
"@types/react-dom": "^18.0.11",
"typescript": "latest"
},
"scripts": {
"dev": "bun --watch dev.tsx"
},
"bun-create": {
"start": "bun run dev"
},
"module": "index.ts",
"type": "module"
}

View File

@@ -0,0 +1,17 @@
import { Counter } from "../Counter";
import { Layout } from "../Layout";
export default function () {
return (
<Layout title="Home">
<Counter />
<div style={{ height: "20px" }}></div>
<p>
<a href="/">Home</a>
</p>
<p>
<a href="/settings">Settings</a>
</p>
</Layout>
);
}

View File

@@ -0,0 +1,17 @@
import { Counter } from "../Counter";
import { Layout } from "../Layout";
export default function () {
return (
<Layout title="Settings">
<Counter />
<div style={{ height: "20px" }}></div>
<p>
<a href="/">Home</a>
</p>
<p>
<a href="/settings">Settings</a>
</p>
</Layout>
);
}

View File

@@ -0,0 +1,16 @@
<svg width="435" height="435" viewBox="0 0 435 435" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M384.167 143.033C383.348 142.139 382.477 141.246 381.606 140.405C380.735 139.563 379.916 138.617 379.045 137.776C378.174 136.935 377.354 135.989 376.483 135.147C375.613 134.306 374.793 133.36 373.922 132.519C373.051 131.678 372.232 130.731 371.361 129.89C370.49 129.049 369.67 128.103 368.799 127.262C367.929 126.421 367.109 125.474 366.238 124.633C391.647 150.26 406.204 185.123 406.758 221.68C406.758 308.791 320.596 379.657 214.66 379.657C155.34 379.657 102.269 357.419 66.9745 322.565L69.5358 325.193L72.0971 327.822L74.6584 330.45L77.2197 333.079L79.781 335.707L82.3424 338.336L84.9037 340.965C120.147 377.291 174.396 400.686 235.15 400.686C341.086 400.686 427.249 329.819 427.249 242.971C427.249 205.856 411.676 170.686 384.167 143.033Z" fill="black"/>
<path d="M393.951 221.68C393.951 301.641 313.68 366.462 214.66 366.462C115.639 366.462 35.3678 301.641 35.3678 221.68C35.3678 172.105 66.1035 128.313 113.334 102.343C160.565 76.3726 189.969 49.7714 214.66 49.7714C239.351 49.7714 260.456 71.4834 315.985 102.343C363.216 128.313 393.951 172.105 393.951 221.68Z" fill="#FBF0DF"/>
<path d="M393.951 221.68C393.926 211.408 392.548 201.187 389.853 191.294C375.868 366.356 167.788 374.768 85.9794 322.407C122.755 351.659 168.136 367.196 214.66 366.462C313.526 366.462 393.951 301.536 393.951 221.68Z" fill="#F6DECE"/>
<path d="M145.658 92.7223C168.556 78.6332 198.984 52.1897 228.901 52.1372C224.298 50.6105 219.496 49.8127 214.66 49.7714C202.263 49.7714 189.047 56.3429 172.398 66.2263C166.609 69.696 160.616 73.5337 154.264 77.5292C142.328 85.0994 128.651 93.6686 113.283 102.238C64.5155 129.312 35.3678 173.945 35.3678 221.68C35.3678 223.783 35.3678 225.886 35.3678 227.936C66.4109 115.381 122.811 106.811 145.658 92.7223Z" fill="#FFFEFC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M199.906 63.072C199.978 75.4853 197.439 87.7682 192.461 99.0821C187.484 110.396 180.186 120.474 171.066 128.629C169.632 129.943 170.759 132.466 172.603 131.73C189.866 124.843 213.174 104.235 203.339 62.6514C202.929 60.2857 199.906 60.9166 199.906 63.072ZM211.535 63.072C217.803 73.5675 221.785 85.3299 223.208 97.5527C224.632 109.776 223.463 122.17 219.782 133.886C219.167 135.726 221.37 137.303 222.6 135.778C233.818 121.058 243.602 91.8286 214.301 60.2857C212.815 58.9189 210.51 61.0217 211.535 62.8617V63.072ZM225.673 62.1783C235.489 69.3099 243.7 78.5187 249.753 89.1837C255.807 99.8487 259.561 111.722 260.763 124.002C260.711 124.445 260.827 124.891 261.087 125.248C261.347 125.605 261.731 125.846 262.159 125.92C262.588 125.994 263.027 125.897 263.387 125.647C263.747 125.398 264 125.016 264.093 124.581C268.806 106.233 266.142 74.9531 227.364 58.7086C225.315 57.8674 223.983 60.7063 225.673 61.968V62.1783ZM131.11 116.853C142.785 113.273 153.596 107.209 162.837 99.0574C172.078 90.9054 179.542 80.8474 184.743 69.5383C185.666 67.6457 188.585 68.3817 188.124 70.4846C179.262 112.542 149.602 121.321 131.161 120.165C129.214 120.217 129.266 117.431 131.11 116.853Z" fill="#CCBEA7"/>
<path d="M214.66 379.657C108.724 379.657 22.5613 308.791 22.5613 221.68C22.5613 169.109 54.2191 120.059 107.238 90.672C122.606 82.2606 135.771 73.7966 147.502 66.384C153.957 62.2834 160.052 58.4457 165.944 54.8709C183.924 43.936 199.292 36.6286 214.66 36.6286C230.028 36.6286 243.449 42.9371 260.251 53.136C265.374 56.1326 270.496 59.392 275.977 62.9669C288.733 71.0629 303.127 80.2103 322.081 90.672C375.1 120.059 406.758 169.056 406.758 221.68C406.758 308.791 320.596 379.657 214.66 379.657ZM214.66 49.7714C202.263 49.7714 189.047 56.3429 172.398 66.2263C166.609 69.696 160.616 73.5337 154.264 77.5292C142.328 85.0995 128.651 93.6686 113.283 102.238C64.5156 129.312 35.3678 173.945 35.3678 221.68C35.3678 301.536 115.793 366.515 214.66 366.515C313.526 366.515 393.951 301.536 393.951 221.68C393.951 173.945 364.804 129.312 315.985 102.343C296.622 91.8286 281.51 81.9452 269.267 74.1646C263.683 70.6423 258.561 67.3829 253.899 64.4914C238.377 55.0286 227.056 49.7714 214.66 49.7714Z" fill="black"/>
<path d="M250.774 260.057C248.473 269.73 243.234 278.401 235.816 284.818C230.246 290.359 223.036 293.837 215.325 294.702C207.383 293.974 199.92 290.487 194.169 284.818C186.826 278.371 181.662 269.703 179.416 260.057C179.341 259.485 179.396 258.902 179.575 258.354C179.753 257.806 180.052 257.308 180.448 256.897C180.843 256.486 181.325 256.173 181.857 255.983C182.388 255.793 182.955 255.73 183.514 255.799H246.727C247.282 255.738 247.843 255.808 248.368 256.002C248.893 256.196 249.368 256.51 249.758 256.92C250.147 257.33 250.441 257.825 250.617 258.369C250.793 258.912 250.847 259.489 250.774 260.057V260.057Z" fill="#B71422"/>
<path d="M194.169 285.239C199.908 290.911 207.344 294.431 215.274 295.227C223.186 294.419 230.603 290.901 236.328 285.239C238.16 283.487 239.871 281.607 241.451 279.614C238.295 275.94 234.44 272.967 230.124 270.879C225.807 268.79 221.12 267.63 216.35 267.47C211.246 267.594 206.249 268.989 201.787 271.535C197.325 274.081 193.533 277.701 190.737 282.085C191.915 283.189 192.94 284.24 194.169 285.239Z" fill="#FF6164"/>
<path d="M194.989 281.086C197.528 277.717 200.779 274.982 204.497 273.088C208.215 271.195 212.302 270.19 216.453 270.151C224.124 270.383 231.433 273.552 236.943 279.035C238.121 277.721 239.248 276.354 240.324 274.987C233.807 268.618 225.195 264.996 216.196 264.841C211.388 264.884 206.648 266.018 202.317 268.163C197.986 270.308 194.171 273.411 191.147 277.248C192.358 278.598 193.641 279.88 194.989 281.086V281.086Z" fill="black"/>
<path d="M215.121 297.856C206.585 297.089 198.552 293.383 192.325 287.342C184.395 280.459 178.814 271.158 176.394 260.793C176.22 259.871 176.25 258.92 176.48 258.01C176.71 257.101 177.136 256.255 177.726 255.536C178.428 254.666 179.314 253.972 180.317 253.508C181.321 253.043 182.414 252.82 183.514 252.855H246.727C247.826 252.831 248.916 253.06 249.917 253.524C250.919 253.987 251.806 254.675 252.516 255.536C253.1 256.258 253.518 257.105 253.74 258.015C253.961 258.925 253.981 259.875 253.796 260.793C251.376 271.158 245.795 280.459 237.865 287.342C231.652 293.373 223.639 297.077 215.121 297.856ZM183.514 258.953C182.694 258.953 182.49 259.321 182.438 259.426C184.604 268.414 189.502 276.461 196.423 282.4C201.484 287.517 208.064 290.755 215.121 291.6C222.159 290.764 228.732 287.567 233.818 282.505C240.718 276.556 245.597 268.511 247.752 259.532C247.64 259.363 247.485 259.23 247.304 259.147C247.124 259.063 246.924 259.033 246.727 259.058L183.514 258.953Z" fill="black"/>
<path d="M292.626 263.317C309.177 263.317 322.593 255.22 322.593 245.232C322.593 235.244 309.177 227.147 292.626 227.147C276.076 227.147 262.659 235.244 262.659 245.232C262.659 255.22 276.076 263.317 292.626 263.317Z" fill="#FEBBD0"/>
<path d="M137.564 263.317C154.115 263.317 167.532 255.22 167.532 245.232C167.532 235.244 154.115 227.147 137.564 227.147C121.014 227.147 107.597 235.244 107.597 245.232C107.597 255.22 121.014 263.317 137.564 263.317Z" fill="#FEBBD0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M151.651 237.977C157.236 237.988 162.698 236.298 167.347 233.121C171.995 229.944 175.621 225.424 177.765 220.132C179.909 214.84 180.476 209.014 179.392 203.391C178.309 197.769 175.625 192.603 171.679 188.546C167.734 184.49 162.705 181.726 157.228 180.604C151.751 179.482 146.074 180.053 140.913 182.243C135.753 184.434 131.341 188.147 128.238 192.912C125.134 197.676 123.477 203.279 123.477 209.01C123.477 216.684 126.444 224.044 131.726 229.474C137.008 234.905 144.174 237.963 151.651 237.977V237.977ZM278.539 237.977C284.13 238.019 289.607 236.355 294.276 233.198C298.944 230.04 302.594 225.531 304.762 220.242C306.929 214.953 307.518 209.122 306.452 203.489C305.386 197.856 302.714 192.675 298.775 188.603C294.836 184.531 289.807 181.751 284.326 180.616C278.845 179.482 273.16 180.043 267.99 182.229C262.821 184.415 258.4 188.128 255.29 192.896C252.179 197.664 250.518 203.272 250.518 209.01C250.504 216.661 253.446 224.005 258.698 229.434C263.95 234.864 271.084 237.935 278.539 237.977V237.977Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M142.943 210.85C145.042 210.861 147.098 210.231 148.848 209.042C150.599 207.852 151.966 206.157 152.776 204.169C153.587 202.182 153.804 199.992 153.401 197.877C152.997 195.763 151.991 193.819 150.51 192.292C149.029 190.765 147.14 189.723 145.082 189.299C143.023 188.875 140.889 189.087 138.948 189.909C137.008 190.731 135.349 192.126 134.181 193.917C133.014 195.707 132.39 197.813 132.39 199.968C132.39 202.845 133.5 205.605 135.478 207.644C137.456 209.684 140.14 210.836 142.943 210.85ZM269.83 210.85C271.93 210.861 273.985 210.231 275.735 209.042C277.486 207.852 278.853 206.157 279.664 204.169C280.474 202.182 280.691 199.992 280.288 197.877C279.885 195.763 278.879 193.819 277.398 192.292C275.917 190.765 274.028 189.723 271.969 189.299C269.911 188.875 267.776 189.087 265.836 189.909C263.895 190.731 262.236 192.126 261.068 193.917C259.901 195.707 259.278 197.813 259.278 199.968C259.278 202.827 260.374 205.571 262.329 207.608C264.285 209.644 266.942 210.809 269.728 210.85H269.83Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,63 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
.App {
text-align: center;
}
.App p {
margin: 0px;
color: white;
}
.App a {
color: white;
}
.App-logo {
height: 150px;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 5s linear;
}
}
.App h3 {
font-size: 2.75rem;
margin: 0px;
}
.App-article {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 12pt;
color: white;
}
.App-link {
color: #61dafb;
font-size: 14pt;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<link rel="stylesheet" href="/index.css"></style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script src="/bundle.js" async type="module"></script>
</body>
</html>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"lib": [
"ESNext"
],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"types": [
"bun-types" // add Bun global
]
}
}

34
templates/react/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
**/*.trace
**/*.zip
**/*.tar.gz
**/*.tgz
**/*.log
package-lock.json
**/*.bun
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build/**/*

Some files were not shown because too many files have changed in this diff Show More