Skip to main content

fractal-file-structuring

Use when creating, moving, splitting, or organizing TypeScript files and folders. Applies fractal tree file-structuring rules which reduce the cognitive overhead of choosing where to put files and ultimately navigating a codebase (once the structure is established and understood).

来源信息

仓库
hashintel/hash
最近来源活动
2026年9月1日 07:54
检测到的 SKILL.md 语言
英语
星标
1,666
分支
123

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
fractal-file-structuring
description
Use when creating, moving, splitting, or organizing TypeScript files and folders. Applies fractal tree file-structuring rules which reduce the cognitive overhead of choosing where to put files and ultimately navigating a codebase (once the structure is established and understood).
license
MIT
metadata
{"triggers":{"type":"domain","enforcement":"suggest","priority":"high","keywords":["TypeScript","JavaScript","file structure","folder structure","create file","create folder","split file","shared folder"],"intent-patterns":["\\b(create|add|move|split|organize|refactor)\\b.*?\\b(file|folder|directory|module|component|hook|type|helper)\\b","\\b(file|folder|directory)\\b.*?\\b(structure|layout|organization|placement)\\b"]}}
# Fractal File Structuring TypeScript and JavaScript files should be organised in a fractal tree structure. Use this skill when deciding where to create, move, split, or organize files and folders in a TypeScript or JavaScript workspace. This guidance is based on HASH's file-structuring approach: https://hash.dev/blog/file-structuring ## Scope Apply this skill to TypeScript and JavaScript source files, including modules, components, hooks, helpers, types, tests, scripts, and entry points. ## Core Rules ### Use kebab-case names Use kebab-case for all TypeScript and JavaScript file and folder names. ```text create-worker-factory.ts playback-settings-menu.tsx button.tsx ``` Avoid PascalCase, camelCase, and mixed-case file names, even for React components. ### Do not create index files Do not add `index.ts`, `index.tsx`, `index.js`, or `index.jsx` files for folder imports. Prefer explicit file entry points with meaningful names. If a subtree needs a public entry point, name that file after the concept it exposes (e.g. `schema.ts`) ### Treat each file as a mini-library A file should expose one or more named exports with a shared semantic purpose. The file name should summarize that purpose (e.g. `users.ts`) If a file contains only one main export, prefer naming the file after that export in kebab-case (e.g. `create-user.ts`) Avoid default exports unless a framework or external API requires them. ### Split outgrown files into private subtrees When a file becomes too large or contains implementation details worth extracting, create a same-named folder next to it and move private pieces there. ```text editor-view.tsx # public mini-library: the component other files import editor-view/ panels.tsx # private entry point imported by editor-view.tsx panels/ simulate-view.tsx # private to panels.tsx calculate-timeline-range.ts # private helper used only by editor-view.tsx create-panel-state.ts # private helper used only by editor-view.tsx ``` Only `editor-view.tsx` should import from direct child mini-libraries such as `editor-view/panels.tsx` and `editor-view/calculate-timeline-range.ts`. Only `editor-view/panels.tsx` should import from `editor-view/panels/*.tsx`. Other files should import from `editor-view.tsx`, not from its private subtree. This keeps `editor-view.tsx` as the API boundary and makes `editor-view/` read as its implementation. If `editor-view/calculate-timeline-range.ts` grows and needs its own private implementation files, create `editor-view/calculate-timeline-range/`. Only `editor-view/calculate-timeline-range.ts` should import from that deeper subtree. ```text editor-view/ calculate-timeline-range.ts calculate-timeline-range/ clamp-time.ts # private to calculate-timeline-range.ts get-visible-duration.ts # private to calculate-timeline-range.ts ``` ### Keep private subtrees private Do not import directly from another file's implementation folder. ```typescript // Avoid: reaches into another file's private subtree import { SimulateView } from "../editor-view/panels/simulate-view"; // Prefer (1): import from a public mini-library (if it is conceptually part of editor-view) import { EditorView } from "../editor-view"; // Prefer (2): move shared code to a shared folder (if it is NOT conceptually part of editor-view) import { Button } from "../shared/button"; ``` If a resource must be available outside the subtree, re-export it from the subtree root only when it is part of that root's public concept. If it is independently useful to sibling branches, move it to an appropriate `shared/` folder instead. ### Put shared resources at the closest fork When multiple sibling branches need the same helper, type, component, constant, or hook, place it in the nearest applicable `shared/` folder. ```text editor-view.tsx editor-view/ shared/ duration-label.tsx # used by both panels.tsx and bottom-section.tsx playback-time.ts # shared formatting/parsing logic for this subtree panels.tsx # imports from panels/ panels/ simulate-view.tsx # private to panels.tsx bottom-section.tsx # imports from bottom-section/ bottom-section/ bottom-bar.tsx # private to bottom-section.tsx ``` Place shared files as deep as possible while still covering all current consumers. Do not move something to a high-level shared folder just because it might be reused later. Here `editor-view.tsx` imports `./editor-view/panels` and `./editor-view/bottom-section`. `panels.tsx` may import `./panels/simulate-view` and `./shared/duration-label`; `bottom-section.tsx` may import `./bottom-section/bottom-bar` and `./shared/duration-label`. Nothing else should import from `panels/` or `bottom-section/` directly. Shared files are mini-libraries too. A shared file can have its own private same-named subtree, and those internals should remain private to that shared file. ```text editor-view/ shared/ playback-time.ts # public to editor-view/* branches playback-time/ parse-playback-time.ts # private to playback-time.ts format-playback-time.ts # private to playback-time.ts ``` If later only `bottom-bar.tsx` uses `duration-label.tsx`, move it beside `bottom-bar.tsx` or under `bottom-bar/`. The folder structure should describe current consumers, not preserve old sharing. ### Use relative imports within a workspace For imports inside the same workspace, use relative paths. Do not introduce workspace-local aliases just to shorten paths. Imports from other workspaces should use the package name. ### Co-locate unit tests Place unit tests next to the file they cover. ```text foo.ts foo.test.ts ``` If a private extracted file needs direct tests, place those tests next to that extracted file. ```text editor-view.tsx editor-view.test.tsx editor-view/ calculate-timeline-range.ts calculate-timeline-range.test.ts ``` Prefer testing through the public mini-library when that gives enough coverage. Add direct tests for private extracted files when the logic is complex enough that tests through the owner would be indirect or brittle. ### Match the current shape Organize files for the code's current relationships, not speculative future reuse. Moving files later is expected and cheaper than adding premature structure now. ## Decision Checklist Before creating a TypeScript or JavaScript file or folder: 1. Identify the semantic concept the file represents. 2. Name the file or folder in kebab-case. 3. If extracting from an existing file, put private implementation files under a same-named folder. 4. If multiple current branches need the resource, put it in the nearest `shared/` folder. 5. Avoid `index` files and implicit folder imports. 6. Use relative imports within the workspace. 7. Co-locate tests with the file under test. ## When Unsure Choose the location that communicates the file's current consumers and API boundary most clearly: - Private implementation detail: place it under the owning file's same-named folder, and import it only from that owner. - Named mini-library: create a normal named file when the concept has its own purpose and exports a small API for nearby consumers. - Shared mini-library: place the named file in the closest `shared/` folder when multiple branches need that API. - Subtree entry point: expose the public API from a named root file, and keep any deeper implementation files private to that root. Do not add broad `components`, `hooks`, `utils`, `types`, or `services` folders unless absolutely necessary. If they exist, these folders MUST only be imported from by files called `components.ts`, `hooks.ts`, etc.
在 GitHub 查看