{"id":48470831,"url":"https://github.com/bchainhub/dapp-starter","last_synced_at":"2026-04-07T06:33:42.433Z","repository":{"id":312411330,"uuid":"1047367480","full_name":"bchainhub/dapp-starter","owner":"bchainhub","description":"Starter for dApp","archived":false,"fork":false,"pushed_at":"2026-03-15T20:10:49.000Z","size":146,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-16T03:32:06.877Z","etag":null,"topics":["blockchain","boilerplate","core","corepass","dapp","starter","starterpack","sveltekit"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bchainhub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-30T09:01:45.000Z","updated_at":"2026-03-15T20:10:52.000Z","dependencies_parsed_at":"2025-08-30T13:18:49.170Z","dependency_job_id":"dc98cdd6-4602-45e6-b7d9-903d715b21f2","html_url":"https://github.com/bchainhub/dapp-starter","commit_stats":null,"previous_names":["bchainhub/sveltekit-starter","bchainhub/dapp-starter"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/bchainhub/dapp-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bchainhub%2Fdapp-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bchainhub%2Fdapp-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bchainhub%2Fdapp-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bchainhub%2Fdapp-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bchainhub","download_url":"https://codeload.github.com/bchainhub/dapp-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bchainhub%2Fdapp-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31503383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","boilerplate","core","corepass","dapp","starter","starterpack","sveltekit"],"created_at":"2026-04-07T06:33:41.871Z","updated_at":"2026-04-07T06:33:42.427Z","avatar_url":"https://github.com/bchainhub.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ĐApp Starter\n\nThis repository ships a one-shot installer that scaffolds a SvelteKit app, adds common deps, optionally merges a template, sets up AI toolkit integration, tweaks `.gitignore`, can copy shared assets from the starter repo, sets a license, and optionally makes a local git commit.\n\n## Quick start\n\n```bash\nnpx github:bchainhub/dapp-starter\n````\n\nWith a custom template:\n\n```bash\nnpx github:bchainhub/dapp-starter -- --template https://github.com/your-org/your-template.git\n```\n\nOr clone and run locally:\n\n```bash\ngit clone https://github.com/bchainhub/dapp-starter.git\ncd dapp-starter\nnpm install\nnode start.mjs\n```\n\n**Template options:** use `--template URL` or `-t URL` to point at a different template repo (default: mota-dapp). You can pin a version in the URL (jsDelivr-style): append `@version` (e.g. `...mota-dapp.git@1.2.3`). Alternatively use `--template-version REF` or `--tv REF` when the URL has no `@version` (e.g. default mota-dapp or a custom URL without a tag). If no version is given, the repo’s default branch is used (from the remote).\n\n## Update from template\n\nTo refresh an existing project from the template (overwrites files with the template’s version, **except `vite.config.ts`**):\n\n```bash\ncd /path/to/your-project\nnode /path/to/dapp-starter/start.mjs --update\n# or: npx github:bchainhub/dapp-starter -- --update\n```\n\nWith a custom template or version in URL:\n\n```bash\nnode start.mjs --update --template https://github.com/your-org/your-template.git\n# version in URL (jsDelivr-style): ...mota-dapp.git@1.2.3\n# or use --tv 1.2.3 when URL has no @version\n```\n\n- **`--update` / `-u`** — run in update mode (no new project; run from project root).\n- **`--template-version REF` / `--tv REF`** — alternative to `URL@version`; use when the URL has no version (e.g. default mota-dapp or custom URL). Clone this branch or tag; if omitted, uses the repo’s default branch.\n- Before overwriting, the script asks: **Create a git commit before updating (breakpoint)?** (default **Yes**). If yes, it runs `git add -A` and `git commit -m \"chore: checkpoint before template update\"`.\n- Template is cloned to a temp dir; its contents are copied over your project (excluding `.git` and `node_modules`). Your **`vite.config.ts`** is backed up and restored so it is never replaced.\n- On success you get: *Project updated from template. vite.config.ts was preserved.*\n\n## Requirements\n\n- Node.js 18+\n- git\n- one package manager: npm, pnpm, yarn, or bun\n\n## What the installer sets up\n\nThe installer:\n\n1. runs `sv create`\n2. installs base dependencies\n3. installs addon tooling\n4. writes `bin/addon.mjs`\n5. maps the command name `addon` in `package.json`\n6. composes a project README\n7. optionally adds translations, skills, template merge, license, and first commit\n\n## Addon CLI\n\nAfter installation, projects can run:\n\n```bash\nnpx addon \u003crepo\u003e \u003cgenerator\u003e \u003caction\u003e [options]\n```\n\nExamples:\n\n```bash\nnpx addon bchainhub@mota-addon-support support install\nnpx addon owner/repo name-of-addon uninstall\nnpx addon owner/repo name-of-addon install -c\nnpx addon owner/repo name-of-addon install -d\n```\n\n**Versioning:** You can pin a release, branch, or commit by appending `#\u003cref\u003e` to the repo (the addon uses tiged, which supports git refs). For example, for release `1.2.3` use a tag such as `v1.2.3` or `1.2.3`:\n\n```bash\nnpx addon owner/repo#v1.2.3 name-of-addon install\nnpx addon owner/repo#1.2.3 name-of-addon install\n```\n\nUse `#branch` for a branch or `#\u003ccommit-hash\u003e` for a specific commit.\n\n**Options (short and long):**\n\n| Flag | Short | Effect |\n| --- | --- | --- |\n| `--cache` | `-c` | Use cache dir for repo (faster re-runs). |\n| `--dry-run` | `-d` | No writes; script/config/lang steps are skipped. |\n| `--no-translations` | `-nt` | Skip _lang (translations) processing. |\n| `--no-scripts` | `-ns` | Skip _scripts execution. |\n| `--no-config` | `-nc` | Skip _config merge. |\n\n## Addon structure\n\nAn addon repository contains generator/action folders. Hidden files `_scripts`, `_config`, and `_lang` can live **either** in the action root **or** inside optional subfolders of the same name:\n\n```text\n\u003crepo\u003e/\n  \u003cgenerator\u003e/\n    \u003caction\u003e/\n      prompt.js\n      *.ejs.t\n      _scripts.ejs.sh    or  _scripts/_scripts.ejs.sh\n      _scripts.sh            _scripts/_scripts.sh\n      _config.ejs.json5  or  _config/_config.ejs.json5\n      _config.json5          _config/_config.json5\n      _lang.sk.json5     or  _lang/sk.json5, _lang/en.ejs.json5, ...\n      _lang.en.json5         _lang/en.json5\n```\n\n### The `_migrations` folder\n\nA `_migrations` folder may be created or copied into your project (e.g. by addons or the template). It is intended for database migrations. It is listed in `.gitignore`, so it **will not be committed** to the git repository - but you can change it to commit it if you want.\n\nYou need to configure your app to use this folder. For example, with **Drizzle ORM** set `out` to `./_migrations` in your config:\n\n```ts\nimport { defineConfig } from \"drizzle-kit\";\n\nexport default defineConfig({\n  schema: \"./src/db/schema.ts\",\n  out: \"./_migrations\",   // 👈 custom migrations folder\n  dialect: \"postgresql\",\n  dbCredentials: {\n    url: process.env.DATABASE_URL!,\n  },\n});\n```\n\nTo execute migrations, add the intended migration command to your `_scripts.ejs.sh` or `_scripts.sh` scripts.\n\nFor example:\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\nnpx drizzle-kit push\n```\n\n## What each file does\n\n### `prompt.js`\n\nOptional. Collects prompt values once.\n\nThose same values are then reused by:\n\n- Hygen templates\n- hidden scripts\n- hidden config\n\nA `prompt.js` file can export either:\n\n- an array of prompt definitions\n- a function returning an answers object\n\nExample array export:\n\n```js\nexport default [\n  {\n    type: 'text',\n    name: 'provider',\n    message: 'Auth provider'\n  },\n  {\n    type: 'text',\n    name: 'route',\n    message: 'Route name',\n    initial: 'auth'\n  }\n];\n```\n\nExample function export:\n\n```js\nexport default async ({ prompts, cwd, generator, action, repo }) =\u003e {\n  const answers = await prompts([\n    {\n      type: 'text',\n      name: 'provider',\n      message: 'Auth provider'\n    }\n  ]);\n\n  return answers;\n};\n```\n\n### `*.ejs.t`\n\nNormal Hygen templates. These generate or inject project files.\n\nExample:\n\n```text\n---\nto: src/routes/auth/+page.svelte\n---\n\u003ch1\u003eHello\u003c/h1\u003e\n```\n\nThese are the only files in the addon action folder that generate normal project output.\n\n### `_scripts.ejs.sh` / `_scripts.sh`\n\nOptional hidden control files.\n\nThey are:\n\n- executed automatically after Hygen\n- never copied into the user project\n- useful for `npm install`, `pnpm add`, formatting, cleanup, and post-generation actions\n\nIf you use `_scripts.ejs.sh`, prompt values are available through EJS:\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\nnpm install \u003c%= packageName %\u003e\necho \"Configured route: \u003c%= routeName %\u003e\"\n```\n\nPrompt values are also exposed as environment variables:\n\n- `ADDON_CONTEXT_JSON`\n- `ADDON_REPO`\n- `ADDON_GENERATOR`\n- `ADDON_ACTION`\n- `ADDON_VAR_\u003cNAME\u003e`\n\nExample:\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\necho \"$ADDON_VAR_PROVIDER\"\necho \"$ADDON_CONTEXT_JSON\"\n```\n\nUse `_scripts.sh` when you do not need EJS interpolation.\nUse `_scripts.ejs.sh` when you want prompt-driven values inserted directly into the script before execution.\n\n### `_config.ejs.json5` / `_config.json5`\n\nOptional hidden config files.\n\nThey are:\n\n- rendered automatically after Hygen\n- never copied into the user project\n- currently applied to the `modules` block in `vite.config.ts`\n\n**Important:** This config is **client-side**. Never put secrets or server-only configuration here—it can end up in the client bundle.\n\nFor secrets and server config, use the official SvelteKit approach: `$env/static/private`, `$env/dynamic/private`, or Vite’s `import.meta.env` (e.g. `VITE_*` for public env vars only).\n\nUse `_config.ejs.json5` when you want prompt values interpolated before merge:\n\n```json5\n{\n  auth: {\n    enabled: true,\n    provider: \"\u003c%= provider %\u003e\",\n    route: \"\u003c%= route %\u003e\"\n  }\n}\n```\n\nUse `_config.json5` when no interpolation is needed.\n\n### `_lang` (translations)\n\nOptional. Language files are merged into `src/i18n/\u003clang\u003e/index.ts` (e.g. `src/i18n/en/index.ts`). They can live in the action root or inside a `_lang/` folder.\n\n- **In action root:** `_lang.\u003ccode\u003e.json5` or `_lang.\u003ccode\u003e.\u003cpathSuffix\u003e.json5`, e.g. `_lang.sk.json5`, `_lang.en.content.ejs.json5`.\n- **In `_lang/` folder:** `\u003ccode\u003e.json5` or `\u003ccode\u003e.\u003cpathSuffix\u003e.json5`, e.g. `sk.json5`, `en.content.ejs.json5`.\n\nUse `.ejs.json5` when you need prompt values interpolated (e.g. `\u003c%= routeName %\u003e`). Use `$path` to target a different object path in the i18n file (default is `modules.\u003cgenerator\u003e`). Use `$remove` to remove keys from the target before merging (see below).\n\n#### Removing old translation strings\n\nTo drop keys that are no longer used (e.g. when uninstalling an addon or deprecating strings), set `$remove` in the language file. It is applied to the target object before your new keys are merged. You can pass:\n\n- **Array** — top-level keys to delete: `\"$remove\": [\"oldTitle\", \"deprecatedLabel\"]`\n- **String** — single key: `\"$remove\": \"oldTitle\"`\n- **Object** — nested removal: use `true` to delete a key, or a nested object to remove keys inside it\n\nExample (remove two top-level keys and one nested key, then add/update others):\n\n```json5\n{\n  \"$path\": \"modules.myAddon\",\n  \"$remove\": {\n    \"oldTitle\": true,\n    \"oldDescription\": true,\n    \"actions\": { \"legacySubmit\": true }\n  },\n  \"title\": \"New title\",\n  \"actions\": { \"submit\": \"Odoslať\" }\n}\n```\n\nExample `_lang.sk.json5` (or `_lang/sk.json5`):\n\n```json5\n{\n  \"$path\": \"modules.myAddon\",\n  \"title\": \"Názov\",\n  \"description\": \"Popis\",\n  \"actions\": {\n    \"submit\": \"Odoslať\",\n    \"cancel\": \"Zrušiť\"\n  }\n}\n```\n\nWith EJS, e.g. `_lang/en.content.ejs.json5`:\n\n```json5\n{\n  \"$path\": \"modules.myAddon\",\n  \"welcome\": \"Welcome to \u003c%= featureName %\u003e\"\n}\n```\n\nSkip translation application with `-nt` or `--no-translations`.\n\n## Config merge behavior\n\nThe hidden config file is merged into the `modules` object in `vite.config.ts`. Remember: this is client-visible config—no secrets or server-only values (use SvelteKit `$env/*/private` or Vite `import.meta.env` instead).\n\nSupported behavior:\n\n- normal keys are merged into `modules`\n- `$remove` removes keys\n- `$expr(\"...\")` injects a raw TypeScript expression instead of a quoted string\n\nExample:\n\n```json5\n{\n  auth: {\n    enabled: true,\n    provider: \"github\"\n  },\n  $remove: {\n    legacyAuth: true\n  }\n}\n```\n\nThat removes `legacyAuth` from `modules` and adds or updates `auth`.\n\n### Raw expressions with `$expr(...)`\n\nExample:\n\n```json5\n{\n  auth: {\n    strategy: \"$expr(resolveAuthStrategy())\",\n    origin: \"$expr(process.env.ORIGIN)\"\n  }\n}\n```\n\nThat is written into `vite.config.ts` as raw TypeScript expressions, not JSON strings.\n\n## Important behavior\n\nThese files are never copied into the target project:\n\n- `prompt.js`\n- `_scripts.ejs.sh`\n- `_scripts.sh`\n- `_config.ejs.json5`\n- `_config.json5`\n\nOnly normal Hygen templates like `*.ejs.t` produce project files.\n\n## Recommended addon action layout\n\n```text\nauth/\n  install/\n    prompt.js\n    auth.config.ts.ejs.t\n    +page.svelte.ejs.t\n    _scripts.ejs.sh\n    _config.ejs.json5\n```\n\nTypical flow:\n\n1. `prompt.js` collects answers\n2. Hygen renders normal templates\n3. `_scripts*` runs automatically\n4. `_config*` is applied automatically\n\n## Example addon\n\n### prompt.js\n\n```js\nexport default [\n  {\n    type: 'text',\n    name: 'provider',\n    message: 'Auth provider'\n  },\n  {\n    type: 'text',\n    name: 'route',\n    message: 'Route name',\n    initial: 'auth'\n  }\n];\n```\n\n### `auth.config.ts.ejs.t`\n\n```text\n---\nto: src/lib/auth/auth.config.ts\n---\nexport const authConfig = {\n  provider: \"\u003c%= provider %\u003e\",\n  route: \"\u003c%= route %\u003e\"\n};\n```\n\n### `+page.svelte.ejs.t`\n\n```text\n---\nto: src/routes/\u003c%= route %\u003e/+page.svelte\n---\n\u003ch1\u003eLogin via \u003c%= provider %\u003e\u003c/h1\u003e\n```\n\n### `_scripts.ejs.sh`\n\n```bash\n#!/usr/bin/env bash\nset -euo pipefail\n\nnpm install @auth/\u003c%= provider %\u003e\n```\n\n### `_config.ejs.json5`\n\n```json5\n{\n  auth: {\n    enabled: true,\n    provider: \"\u003c%= provider %\u003e\",\n    route: \"\u003c%= route %\u003e\"\n  },\n  $remove: {\n    legacyAuth: true\n  }\n}\n```\n\n## Dry run\n\nUse:\n\n```bash\nnpx addon owner/repo name-of-addon action --dry-run\n```\n\nThis runs Hygen generation but skips hidden scripts and hidden config application.\n\n## Cache\n\nUse:\n\n```bash\nnpx addon owner/repo name-of-addon action --cache\n```\n\nThis keeps addon sources under `.addon-cache/` so they do not need to be downloaded every time.\n\n## Resources\n\n- [📦 MOTA addons search](https://github.com/topics/mota-addon)\n- [📖 MOTA skills search](https://skills.sh)\n\n## License\n\nThis starter is licensed under the [CORE License](https://github.com/bchainhub/core-license).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbchainhub%2Fdapp-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbchainhub%2Fdapp-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbchainhub%2Fdapp-starter/lists"}