לכל מפתח יש את התיקייה הזו. זו שנקראת utils או helpers שאתה מעתיק ממאגר קוד (repo) למאגר קוד אחר. אתה מדביק אותה, מבלה עשרים דקות במחיקת הפניות לסכמות בסיסי נתונים ישנות, בשליפת בדיקות אימות (auth) שלא רלוונטיות, ובשינוי שמות של משתנים כדי שה-linter החדש שלך יפסיק לצרוח. נהגתי לעשות זאת עם מערכת עיצוב שבניתי, ה-Dynamic Theme Kit. היא התחילה כפיצ'ר בתוך אפליקציה אחת, ולמשך חודשים התייחסתי אליה כאל כלי נייד. טעיתי. העתקת קוד היא לא שימוש חוזר. זו כפילות עם שלבים מיותרים.

מלכודת הגישה של פרויקט יחיד

כשבונים פיצ'ר בתוך פרויקט, יוצרים מאות הנחות בלתי נראות. פלטת הצבעים עשויה להניח הגדרת CSS-in-JS מסוימת. סולם המרווחים (spacing scale) עשוי להתייחס ל-design token מתוך מדריך המותג של החברה שלך. המתג בין מצב בהיר לכהה עשוי לקרוא ל-endpoint של העדפות משתמש הייחודי ל-backend של אותה אפליקציה. התלויות הללו מרגישות בלתי מזיקות כי בתוך הפרויקט, הן אכן בלתי מזיקות. הן שייכות לשם.

הבעיה מתחילה כשמנסים להוציא את הקוד הזה החוצה. אתה מגלה שהרכיב ה"ניתן לשימוש חוזר" הוא למעשה רשת של מחרוזות נסתרות המחברות אותו למאגר הקוד ההוא. למדתי את זה עם DTK. היא יצרה משתני עיצוב (theme variables), כן. אבל היא גם ציפתה למבנה תיקיות ספציפי. היא ייבאה הגדרת טיפוסים (type definition) ממקום עמוק בתוך ספריית ה-types של האפליקציה המקורית. היא הניחה קיומו של אובייקט קונפיגורציה גלובלי שהיה קיים רק במאגר (repository) ההוא. מעולם לא שמתי לב לזה כי בתוך הפרויקט הזה, הכל תמיד היה שם.

הפיכת DTK לחבילה (package) עצמאית דרשה ניתוח, לא הרחבה. לא הייתי צריך יותר פיצ'רים. הייתי צריך פחות קשרים.

חילוץ ה-Dynamic Theme Kit

העבודה הקשה ביותר הייתה לשבת מול בסיס הקוד ולשאול, עבור כל פונקציה וכל export: האם זה משרת את לוגיקת העיצוב (theming logic), או שזה משרת את הפרויקט? הסרתי הגדרות עיצוב מוגדרות מראש (styling presets). הסרתי את ההנחה שהצרכן יהיה אפליקציית React. מחקתי לחלוטין את פלטות הצבעים כברירת מחדל. בפרויקט המקורי הייתה אסתטיקה תאגידית של כחול-כהה וסלייט (navy-and-slate) שמוטמעת בברירת המחדל. זה היה חייב ללכת. חבילה לא יכולה לספק את צבעי המותג שלך.

ה-kit החדש יעשה דבר אחד בדיוק. הוא מקבל אובייקט קונפיגורציה — כמה ערכי צבע, כמה מספרי מרווחים, כמה סולמות טיפוגרפיה — והוא מייצר CSS custom properties. זה הכל. הוא לא מחיל אותם. הוא לא מחליט איפה

Personal projects are sandboxes. They do not have deadlines, stakeholders, or legacy CSS that predates your package. The real test came when I integrated DTK into Web Weavers World, my business site. This was a live property with existing styles, client expectations, and analytics to consider. If the package broke something, I could not just delete the repo and start over.

I added DTK to the build pipeline, pointed it at a new color configuration, and let it generate a fresh set of CSS variables. The integration took an afternoon, not a week. That was the signal. Previously, adding a new theme meant writing new CSS, hunting down hardcoded hex values in twenty files, and hoping I did not miss an edge case. Now I add a palette to the configuration file, DTK generates the variables, and the rest of the site consumes them. The theme logic went from being a fragile manual process to something I trust enough to hand off to collaborators.

Three Questions That Changed How I Build

Going through this process forced me to formalize a mental checklist I now use before I abstract anything:

  • Is this variable truly generic? If the name or the logic references a domain concept from the original project, it stays behind.
  • Does this belong in the package or the application? Business rules, brand identities, and layout assumptions live in the app. Plumbing that generates standardized output lives in the package.
  • Am I solving a reusable problem or a project-specific one? This is the hardest to answer honestly. We like to think our solutions are universal. Usually they are local.

Answering these questions forced me to simplify my design, often by removing code rather than adding it. DTK taught me that reuse is not a gift you give yourself. It is a discipline you practice by saying no to convenience.

A Different Way to Think About Refactoring

I used to measure refactors by how much shorter they made the code. Fewer lines felt like progress. Now I measure them by how many doors they open. The Dynamic Theme Kit is not elegant because it is concise. It is useful because it survived three unrelated personal projects and a production business site without needing to change its internals.

That is the metric that matters. Code that works once is an expense. Code that works repeatedly is an asset. Before I start any feature now, I stop. I ask if I am building something I will need again. If the answer is yes, I build it differently from the first line. I isolate the inputs. I define the outputs. I remove the assumptions.

The best refactor does not make your code shorter. It makes your code work in places you have not imagined yet.