├── .nvmrc ├── .husky ├── pre-commit ├── pre-push └── commit-msg ├── .npmrc ├── public ├── _redirects ├── robots.txt ├── assets │ ├── chakra-ui-logomark-colored.svg │ ├── vite-logo.svg │ ├── ts-logo-512.svg │ ├── react-icon.svg │ ├── 404 Error-rafiki.svg │ └── Building blocks-amico.svg └── favicon.svg ├── src ├── lib │ ├── utils │ │ ├── sample.ts │ │ └── sample.test.ts │ ├── services │ │ └── constants.ts │ ├── styles │ │ └── theme │ │ │ └── index.ts │ ├── components │ │ └── ui │ │ │ ├── provider.tsx │ │ │ ├── button.tsx │ │ │ └── color-mode.tsx │ ├── pages │ │ ├── 404 │ │ │ └── index.tsx │ │ └── home │ │ │ ├── index.tsx │ │ │ └── components │ │ │ ├── some-text.tsx │ │ │ ├── some-image.tsx │ │ │ └── cta-section.tsx │ └── layout │ │ ├── components │ │ ├── header.tsx │ │ ├── footer.tsx │ │ └── meta.tsx │ │ └── index.tsx ├── routes │ ├── index.tsx │ └── __root.tsx ├── env.d.ts ├── main.tsx └── routeTree.gen.ts ├── vercel.json ├── .vscode ├── settings.template.json └── extensions.json ├── netlify.toml ├── nixpacks.toml ├── .lintstagedrc.json ├── tsconfig.node.json ├── index.html ├── knip.ts ├── pwa-assets.config.ts ├── .github └── workflows │ ├── update-license.yml │ └── release.yml ├── .gitignore ├── commitlint.config.ts ├── vitest.config.ts ├── renovate.json ├── turbo.json ├── tsconfig.json ├── LICENSE ├── vite.config.ts ├── README.md ├── package.json └── biome.json /.nvmrc: -------------------------------------------------------------------------------- 1 | v24.11.1 -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | pnpm check:turbo 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | enable-pre-post-scripts=true 2 | -------------------------------------------------------------------------------- /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | pnpm commitlint --edit $1 2 | -------------------------------------------------------------------------------- /src/lib/utils/sample.ts: -------------------------------------------------------------------------------- 1 | export const sum = (a: number, b: number) => { 2 | return a + b; 3 | }; 4 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://openapi.vercel.sh/vercel.json", 3 | "buildCommand": "turbo run build" 4 | } 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # * 2 | User-agent: * 3 | Allow: / 4 | 5 | # Host 6 | Host: https://vite-react-chakra-starter.sznm.dev 7 | -------------------------------------------------------------------------------- /src/lib/services/constants.ts: -------------------------------------------------------------------------------- 1 | import { QueryClient } from '@tanstack/react-query'; 2 | 3 | export const queryClient = new QueryClient(); 4 | -------------------------------------------------------------------------------- /src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from '@tanstack/react-router'; 2 | 3 | import Home from '@/lib/pages/home'; 4 | 5 | export const Route = createFileRoute('/')({ 6 | component: Home, 7 | }); 8 | -------------------------------------------------------------------------------- /.vscode/settings.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.preferences.importModuleSpecifier": "non-relative", 4 | "editor.defaultFormatter": "biomejs.biome" 5 | } 6 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[redirects]] 2 | from="/*" 3 | to="/index.html" 4 | status=200 5 | 6 | [build] 7 | command = 'pnpm build' 8 | 9 | [build.environment] 10 | NODE_VERSION="22" 11 | COREPACK_INTEGRITY_KEYS="0" 12 | -------------------------------------------------------------------------------- /nixpacks.toml: -------------------------------------------------------------------------------- 1 | # https://github.com/railwayapp/nixpacks/issues/1340#issuecomment-3084046921 2 | buildImage = 'ghcr.io/railwayapp/nixpacks:latest' 3 | 4 | [phases.setup] 5 | nixpkgsArchive = '11cb3517b3af6af300dd6c055aeda73c9bf52c48' 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "biomejs.biome", 4 | "dsznajder.es7-react-js-snippets", 5 | "mhutchie.git-graph", 6 | "oderwat.indent-rainbow", 7 | "yoavbls.pretty-ts-errors" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [ 3 | "biome check --write --no-errors-on-unmatched --error-on-warnings" 4 | ], 5 | "*.{ts,js,json,md}": [ 6 | "biome check --write --no-errors-on-unmatched --error-on-warnings" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/consistent-type-definitions */ 2 | /// 3 | 4 | // biome-ignore lint/complexity/noBannedTypes: - 5 | type ImportMetaEnv = {}; 6 | 7 | interface ImportMeta { 8 | readonly env: ImportMetaEnv; 9 | } 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vite React Chakra Starter 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /knip.ts: -------------------------------------------------------------------------------- 1 | import type { KnipConfig } from 'knip'; 2 | 3 | const config: KnipConfig = { 4 | entry: ['src/main.tsx'], 5 | ignore: ['src/**/*.gen.ts'], 6 | project: ['src/**/*.{ts,tsx,js,jsx,css,scss}'], 7 | ignoreBinaries: ['changelogithub'], 8 | }; 9 | 10 | export default config; 11 | -------------------------------------------------------------------------------- /pwa-assets.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | minimal2023Preset as preset, 4 | } from '@vite-pwa/assets-generator/config'; 5 | 6 | export default defineConfig({ 7 | headLinkOptions: { 8 | preset: '2023', 9 | }, 10 | preset, 11 | images: ['public/favicon.svg'], 12 | }); 13 | -------------------------------------------------------------------------------- /.github/workflows/update-license.yml: -------------------------------------------------------------------------------- 1 | name: Update License 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # Update the license once a year on January 1 7 | - cron: "0 0 1 1 *" 8 | 9 | jobs: 10 | update-license: 11 | uses: agustinusnathaniel/workflows/.github/workflows/update-license.yml@main 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | build 5 | dist-ssr 6 | *.local 7 | 8 | yarn-error.log* 9 | .pnpm-debug.log* 10 | 11 | # TS 12 | *.tsbuildinfo 13 | 14 | # Turbo 15 | .turbo 16 | 17 | .vscode/settings.json 18 | 19 | stats.* 20 | 21 | # Test 22 | coverage/ 23 | 24 | # ESLint 25 | .eslintcache 26 | 27 | .tanstack -------------------------------------------------------------------------------- /commitlint.config.ts: -------------------------------------------------------------------------------- 1 | import { RuleConfigSeverity, type UserConfig } from '@commitlint/types'; 2 | 3 | const commitlintConfiguration: UserConfig = { 4 | extends: ['@commitlint/config-conventional'], 5 | rules: { 6 | 'scope-case': [RuleConfigSeverity.Error, 'always', 'kebab-case'], 7 | }, 8 | }; 9 | 10 | export default commitlintConfiguration; 11 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-extraneous-dependencies */ 2 | import tsConfigPaths from 'vite-tsconfig-paths'; 3 | import { defineConfig } from 'vitest/config'; 4 | 5 | export default defineConfig({ 6 | test: { 7 | coverage: { 8 | include: ['src/lib/utils/**/**.{ts,tsx,js,jsx}'], 9 | }, 10 | }, 11 | plugins: [tsConfigPaths()], 12 | }); 13 | -------------------------------------------------------------------------------- /src/lib/styles/theme/index.ts: -------------------------------------------------------------------------------- 1 | import { createSystem, defaultConfig } from '@chakra-ui/react'; 2 | 3 | export const theme = createSystem(defaultConfig, { 4 | theme: { 5 | tokens: { 6 | fonts: { 7 | heading: { value: 'Plus Jakarta Sans Variable, sans-serif' }, 8 | body: { value: 'Plus Jakarta Sans Variable, sans-serif' }, 9 | }, 10 | }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base", "group:all"], 4 | "major": { 5 | "enabled": false 6 | }, 7 | "updatePinnedDependencies": false, 8 | "stabilityDays": 2, 9 | "timezone": "Asia/Jakarta", 10 | "schedule": ["before 1am on the first day of the month"], 11 | "rangeStrategy": "bump", 12 | "ignoreDeps": ["node", "pnpm"] 13 | } 14 | -------------------------------------------------------------------------------- /src/lib/components/ui/provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { ChakraProvider } from '@chakra-ui/react'; 4 | 5 | import { theme } from '@/lib/styles/theme'; 6 | 7 | import { ColorModeProvider } from './color-mode'; 8 | 9 | export function Provider(props: React.PropsWithChildren) { 10 | return ( 11 | 12 | {props.children} 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/lib/pages/home/index.tsx: -------------------------------------------------------------------------------- 1 | import { Grid } from '@chakra-ui/react'; 2 | 3 | import { CTASection } from './components/cta-section'; 4 | import { SomeImage } from './components/some-image'; 5 | import { SomeText } from './components/some-text'; 6 | 7 | const Home = () => { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default Home; 18 | -------------------------------------------------------------------------------- /src/lib/pages/home/components/some-text.tsx: -------------------------------------------------------------------------------- 1 | import { Grid, Heading, Text } from '@chakra-ui/react'; 2 | 3 | export const SomeText = () => { 4 | return ( 5 | 6 | 7 | vite-react-chakra-starter 8 | 9 | 10 | This is a vite react template with Chakra-UI and TypeScript setup. 11 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: 22.x 19 | 20 | - run: npx changelogithub 21 | env: 22 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 23 | -------------------------------------------------------------------------------- /src/lib/layout/components/header.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Flex } from '@chakra-ui/react'; 2 | 3 | import { ColorModeButton } from '@/lib/components/ui/color-mode'; 4 | 5 | export const Header = () => { 6 | return ( 7 | 15 | 16 | 17 | 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /src/lib/utils/sample.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from 'vitest'; 2 | 3 | import { sum } from './sample'; 4 | 5 | describe('sum', () => { 6 | test('positive number additions', () => { 7 | expect(sum(50, 41)).toBe(91); 8 | expect(sum(60, 41)).toBe(101); 9 | }); 10 | 11 | test('negative number additions', () => { 12 | expect(sum(-50, -41)).toBe(-91); 13 | expect(sum(-60, -41)).toBe(-101); 14 | }); 15 | 16 | test('positive and negative number additions', () => { 17 | expect(sum(-50, 41)).toBe(-9); 18 | expect(sum(-60, 41)).toBe(-19); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /src/lib/layout/components/footer.tsx: -------------------------------------------------------------------------------- 1 | import { Flex, Link, Text } from '@chakra-ui/react'; 2 | 3 | export const Footer = () => { 4 | return ( 5 | 12 | 13 | {new Date().getFullYear()} -{' '} 14 | 19 | agustinusnathaniel.com 20 | 21 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "tasks": { 4 | "type:check": { 5 | "inputs": ["tsconfig.json", "src/**"], 6 | "outputs": ["*.tsbuildinfo"] 7 | }, 8 | "biome:check": { 9 | "outputs": [], 10 | "inputs": ["biome.json", "src/**"] 11 | }, 12 | "biome:ci": { 13 | "outputs": [], 14 | "inputs": ["biome.json", "src/**"] 15 | }, 16 | "build": { 17 | "dependsOn": ["type:check"], 18 | "outputs": ["build/client/**", "public/**"], 19 | "env": [] 20 | }, 21 | "test": { 22 | "outputs": ["node_modules/.vite/vitest/**/results.json"], 23 | "inputs": ["vitest.config.ts", "src/**"] 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/lib/layout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Flex } from '@chakra-ui/react'; 2 | import type { ReactNode } from 'react'; 3 | 4 | import { Footer } from './components/footer'; 5 | import { Header } from './components/header'; 6 | import { Meta } from './components/meta'; 7 | 8 | type LayoutProps = { 9 | children: ReactNode; 10 | }; 11 | 12 | export const Layout = ({ children }: LayoutProps) => { 13 | return ( 14 | 15 | 16 | 17 |
18 | 19 | {children} 20 | 21 |