惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
博客园 - 司徒正美
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - Franky
B
Blog
V
V2EX
J
Java Code Geeks
D
Docker
博客园 - 叶小钗
The Cloudflare Blog
量子位
博客园_首页
MongoDB | Blog
MongoDB | Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Self-similar: a versatile folder pattern for code
Jonathan · 2026-05-07 · via DEV Community

“The word 'isomorphism' applies when two complex structures can be mapped onto each other, in such a way that to each part of one structure there is a corresponding part in the other structure, where "corresponding" means that the two part play similar roles in their respective structures.”

– Douglas HOFSTADTER

Gödel, Escher, Bach • Meaning and Form in Mathematics • pp. 57


I've seen various trends come and go in code folder and file structure.

The two big ones in the front-end space seem to have been:

  • Function-focussed.
    • 📁 controllers
    • 📁 views
    • 📁 models
    • etc...
  • Feature-focussed.
    • 📁 posts
    • 📁 comments
    • 📁 likes
    • etc...

There have been various efforts to combine them, such as the feature-sliced design.

For example, we can have:

  • 📁 posts
    • 📁 controllers
    • 📄 list.ts
    • 📄 detail.ts
    • 📄 create.ts
    • 📄 delete.ts
    • 📁 views
    • 📄 list.tsx
    • 📄 detail.tsx
    • 📄 create.tsx
    • 📄 deleted-message.tsx
    • 📁 models
    • 📄 post.ts
  • 📁 comments
    • 📁 controllers
    • ...
    • 📁 views
    • ...
    • 📁 models
    • ...
  • 📁 likes
    • ...

Overall I like the above strategy. But I wanted to take it one step further.

You see... sometimes I feel I want to have the best of both worlds. A bit of functional and a bit of feature.

  • Some kinds of things seem to fit neatly into a single feature.
    • 📁 posts
    • 📁 comments
    • 📁 likes
  • Other kinds of things seem to make more sense as functional pieces.
    • 📁 hooks
    • 📁 utils
    • 📁 mixins

What I've settled on is: consistency in naming with freedom in ordering.

Rules

Here are the rules of the self-similar folder pattern:

  1. Any word can be pluralized: comment => comments.
  2. Any word can be combined with any other word (or combination of words) by a dash: delete, comment => delete-comment.
  3. Any word (or combination of words) can be used to name a folder or file, at any nesting level.

Process

First we start with listing all of the unique "naming words" or tokens in our present file/folder structure (non-pluralized):

border comment controller create
delete deleted detail fetch
get hook like list
local mixin model post
recessed relieved storage use
util view

Then we group similar words, based on how they seem to be used in the system and how they seem to naturally fit together. (Note that words can be re-used as many times as needed.)

Aside: This technique has long been known in UX design as card sorting.

  • border, recessed, mixin
  • comment, list, create, delete
  • post, detail, list, create, delete
  • like, list, create, delete
  • etc...

It becomes clear that certain functions cluster around a single feature. For example, post has detail, list, create and delete. For these cases, we adopt feature grouping.

It becomes similarly clear that certain functions stand alone or group with other similar functions. For example, border variants recessed and relieved are each a kind of mixin, which I consider a function not a feature. For these cases, we adopt function grouping.

Based on the groupings, we order the words by priority:

And then nest them in order.

The end-result:

  • 📁 posts
    • 📁 controllers
    • 📄 list.ts
    • 📄 detail.ts
    • 📄 create.ts
    • 📄 delete.ts
    • 📁 views
    • 📄 list.tsx
    • 📄 detail.tsx
    • 📄 create.tsx
    • 📄 deleted-message.tsx
    • 📁 models
    • 📄 post.ts
    • 📁 hooks
    • 📄 like-post.ts
  • 📁 comments
    • 📁 controllers
    • ...
    • 📁 views
    • ...
    • 📁 models
    • ...
  • 📁 likes
    • ...
  • 📁 hooks
    • 📁 local-storage
    • 📄 hook
  • 📁 utils
    • 📁 fetch
    • 📄 get.ts
    • 📄 delete.ts
    • 📄 post.ts
  • 📁 mixins
    • 📁 border
    • 📄 recessed.ts
    • 📄 relieved.ts

Notice that this folder structure exhibits a kind of self-similarity.

For example:

  • detail can appear within either controllers (as a controller) or views (as a view).
  • controllers, views and models can appear within features posts, comments and likes.
  • hooks can be grouped together with other hooks, such as local-storage/hook.ts, but alternatively, they can be grouped with a feature, such as posts/hooks/like.ts.

This self-similarity makes the folder structure extremely powerful yet flexible. Any word can be a unit of re-use, but no word is "locked in" to only appearing in one part of the structure. The form is extremely flexible, yet also extremely rigorous.

When to use

It requires effort and teamwork to keep this kind of folder structure well organised. Card sorting is a high-energy, collaborative activity. So this folder structure is probably not a good fit for all scenarios.

If you are a team of, say, Ruby engineers, in a medium-sized corporation, who want to play it safe and follow an established pattern, there's nothing wrong with going function-based. The enemy here is risk of losing control.

If you are a startup, who need to move fast, and don't have time for any hand-wavy card-sorting UX nonsense, there's nothing wrong with going feature-based. The enemy here is time.

Where I see the sweet-spot for this kind of structure is a long-term cleanup operation in a fairly complex project but a small team of very experienced polyglot programmers. Lots of collaboration, lots of care, but also lots of autonomy. The enemy here is complexity of the code itself, and a technique that accepts complexity without succumbing to it is probably the right tool for the job.