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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
43 changes: 43 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/_gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build
/dist

# misc
.DS_Store
*.pem
.agents

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
1 change: 1 addition & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/_nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"ignorePatterns": [".agents/**", "AGENTS.md", "CLAUDE.md"]
}
41 changes: 41 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/_package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "typegpu-nextjs-bare-project",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"check": "oxlint && oxfmt --check",
"fix": "oxlint --fix && oxfmt",
"types": "tsc --p ./tsconfig.json --noEmit"
},
"dependencies": {
"@typegpu/react": "^0.11.1",
"next": "16.2.7",
"react": "19.2.4",
"react-dom": "19.2.4",
"typegpu": "^0.11.8"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@webgpu/types": "^0.1.70",
"eslint-plugin-typegpu": "^0.11.1",
"oxfmt": "^0.49.0",
"oxlint": "^1.64.0",
"tailwindcss": "^4",
"typescript": "npm:tsover@6.0.1",
"unplugin-typegpu": "^0.11.4"
},
"overrides": {
"typescript": "npm:tsover@6.0.1"
},
"pnpm": {
"overrides": {
"typescript": "npm:tsover@6.0.1"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.enablePromptUseWorkspaceTsdk": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Folder-specific settings
//
// For a full list of overridable settings, and general information on folder-specific settings,
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
{
"lsp": {
"vtsls": {
"settings": {
"typescript": {
"tsdk": "node_modules/typescript/lib"
}
}
}
}
}
10 changes: 10 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use client';

import React from 'react';
import dynamic from 'next/dynamic';

const ShaderInner = dynamic(() => import('./ShaderInner.tsx'), { ssr: false });

export default function Canvas({ className }: { className?: string }) {
return <ShaderInner className={className} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client';

import React, { useMemo } from 'react';
import { useConfigureContext, useFrame, useRoot } from '@typegpu/react';
import { common, d } from 'typegpu';

export default function ShaderInner({ className }: { className?: string }) {
const { ref, ctxRef } = useConfigureContext({ autoResize: true, alphaMode: 'premultiplied' });

const root = useRoot();
const renderPipeline = useMemo(
() =>
root.createRenderPipeline({
vertex: common.fullScreenTriangle,
fragment: ({ uv }) => {
'use gpu';
return d.vec4f(0.55, uv, 1);
},
}),
[root],
);

useFrame(() => {
if (!ctxRef.current) return;
renderPipeline.withColorAttachment({ view: ctxRef.current }).draw(3);
});

return <canvas ref={ref} className={className} />;
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@import 'tailwindcss';

:root {
--text: #6b6375;
--text-h: #08060d;
--bg: #fff;
--border: #e5e4e7;
--social-bg: rgba(244, 243, 236, 0.5);
--shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
}

@theme inline {
--color-bg: var(--bg);
--color-text: var(--text);
--color-text-h: var(--text-h);
--color-border: var(--border);
--color-social: var(--social-bg);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}

@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--text-h: #f3f4f6;
--bg: #16171d;
--border: #2e303a;
--social-bg: rgba(47, 48, 58, 0.5);
--shadow: rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
}

.button-icon {
filter: invert(1) brightness(2);
}
}

body {
margin: 0;
background: var(--bg);
color: var(--text);
}

.ticks {
position: relative;
width: 100%;
}

.ticks::before,
.ticks::after {
content: '';
position: absolute;
top: -4.5px;
border: 5px solid transparent;
}

.ticks::before {
left: 0;
border-left-color: var(--border);
}

.ticks::after {
right: 0;
border-right-color: var(--border);
}
22 changes: 22 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import type { Metadata } from 'next';

// oxlint-disable-next-line import/no-unassigned-import
import './globals.css';

export const metadata: Metadata = {
title: 'typegpu-nextjs-bare-project',
description: 'TypeGPU + Next.js',
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" className={`h-full antialiased`}>
<body className="flex min-h-full flex-col font-sans">{children}</body>
</html>
);
}
133 changes: 133 additions & 0 deletions packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React from 'react';

import Shader from './Shader.tsx';
import typegpuLogoDark from '../public/typegpu-logo-dark.svg';
import typegpuLogoLight from '../public/typegpu-logo-light.svg';
import nextLogo from '../public/next.svg';

export function generateStaticParams() {
return [{ slug: [''] }];
}

export default function Page() {
return (
<div className="mx-auto flex h-svh w-[1126px] max-w-full flex-col border-x border-border">
<section className="flex grow flex-col place-content-center place-items-center pt-8 pb-8 max-[1024px]:pt-8 max-[1024px]:pb-6">
<Shader className="h-[min(55vw,55svh)] w-[min(55vw,55svh)] max-w-full" />
</section>

<div className="ticks" />

<section className="flex border-t border-border text-left max-[1024px]:flex-col max-[1024px]:text-center">
{/* TypeGPU */}
<div className="min-w-0 flex-1 border-r border-border p-8 max-[1024px]:border-r-0 max-[1024px]:border-b max-[1024px]:px-5 max-[1024px]:py-6">
<picture className="mb-2 flex h-7 items-center max-[1024px]:h-6 max-[1024px]:justify-center">
<source srcSet={typegpuLogoDark.src} media="(prefers-color-scheme: dark)" />
<img
className="h-12 w-auto max-[1024px]:h-8"
src={typegpuLogoLight.src}
alt="TypeGPU"
/>
</picture>

<p>Type-safe WebGPU</p>

<ul className="mt-8 flex flex-wrap gap-2 max-[1024px]:mt-5 max-[1024px]:justify-center">
<li className="max-[1024px]:flex-[1_1_calc(50%-8px)]">
<a
className="flex items-center gap-2 rounded-md bg-social px-3 py-1.5 text-base text-text-h transition-shadow hover:shadow-[var(--shadow)] max-[1024px]:w-full max-[1024px]:justify-center"
href="https://docs.swmansion.com/TypeGPU"
target="_blank"
rel="noreferrer"
>
<svg
className="button-icon h-[18px] w-[18px]"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#documentation-icon" />
</svg>
Documentation
</a>
</li>
<li className="max-[1024px]:flex-[1_1_calc(50%-8px)]">
<a
className="flex items-center gap-2 rounded-md bg-social px-3 py-1.5 text-base text-text-h transition-shadow hover:shadow-[var(--shadow)] max-[1024px]:w-full max-[1024px]:justify-center"
href="https://github.com/software-mansion/typegpu"
target="_blank"
rel="noreferrer"
>
<svg
className="button-icon h-[18px] w-[18px]"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#github-icon" />
</svg>
GitHub
</a>
</li>
<li className="max-[1024px]:flex-[1_1_calc(50%-8px)]">
<a
className="flex items-center gap-2 rounded-md bg-social px-3 py-1.5 text-base text-text-h transition-shadow hover:shadow-[var(--shadow)] max-[1024px]:w-full max-[1024px]:justify-center"
href="https://discord.gg/8jpfgDqPcM"
target="_blank"
rel="noreferrer"
>
<svg
className="button-icon h-[18px] w-[18px]"
role="presentation"
aria-hidden="true"
>
<use href="/icons.svg#discord-icon" />
</svg>
Discord
</a>
</li>
</ul>
</div>

{/* Next.js */}
<div className="min-w-0 flex-1 p-8 max-[1024px]:px-5 max-[1024px]:py-6">
<h2 className="mb-2 flex h-7 items-center gap-2 text-2xl font-medium leading-tight tracking-tight text-text-h max-[1024px]:h-6 max-[1024px]:justify-center max-[1024px]:text-xl">
<picture>
<img
className="h-[22px] w-auto dark:invert"
src={nextLogo.src}
alt=""
aria-hidden="true"
/>
</picture>
</h2>

<p>The React framework</p>

<ul className="mt-8 flex flex-wrap gap-2 max-[1024px]:mt-5 max-[1024px]:justify-center">
<li className="max-[1024px]:flex-[1_1_calc(50%-8px)]">
<a
className="flex items-center gap-2 rounded-md bg-social px-3 py-1.5 text-base text-text-h transition-shadow hover:shadow-[var(--shadow)] max-[1024px]:w-full max-[1024px]:justify-center"
href="https://nextjs.org"
target="_blank"
rel="noreferrer"
>
<picture>
<img
className="h-[18px] w-[18px] object-contain dark:invert"
src={nextLogo.src}
alt=""
aria-hidden="true"
/>
</picture>
Explore Next.js
</a>
</li>
</ul>
</div>
</section>

<div className="ticks" />

<section className="h-[88px] border-t border-border max-[1024px]:h-12" />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = (api) => {
api.cache(true);
return {
presets: ['next/babel'],
plugins: ['unplugin-typegpu/babel'],
};
};
Loading
Loading