Clean code isn’t just about formatting—it’s about deleting the right things!. Recently came across this tool called knip, surprised by how much unused stuff was lying around—dependencies, exports, even files. Over time, projects just grow cluttered. We add things, refactor, forget to clean up. Knip basically tells you: this is dead, you can safely delete it. It reminded me that: Clean code is not about writing more code. It’s about removing the unnecessary parts. If you maintain a large codebase, this is a pretty useful tool. https://knip.dev/ PS : It also improves overall test coverage and reduce bundle size as a side effect.
Clean Code with Knip: Remove Unused Dependencies and Files
More Relevant Posts
-
🚨 Ever opened a codebase and thought, “Who nested all these callbacks and why am I stuck here?” 😵💫 💡 If you’ve worked with asynchronous JavaScript, chances are you’ve run into callbacks — and maybe even experienced the dreaded callback hell. 🔹 Callback • A function passed into another function as an argument • Executed after a task is completed (asynchronous behavior) • Common in APIs, file handling, and event handling 🔹 Why Callbacks Matter • Enable non-blocking operations • Help handle async tasks like fetching data or reading files • Core concept before Promises and async/await 🔹 Callback Hell 😬 • Happens when callbacks are nested inside callbacks… inside callbacks • Makes code hard to read, debug, and maintain • Often forms a “pyramid of doom” structure 🔹 Example Pattern • One async task depends on another • Leads to deep nesting • Error handling becomes messy ⚡ Quick rule many developers follow: • Use callbacks → for simple async tasks • Avoid deep nesting → refactor early • Prefer Promises / async-await → for cleaner, scalable code 📌 Callback hell isn’t a bug — it’s a signal that your code needs better structure. hashtag#JavaScript hashtag#WebDevelopment hashtag#AsyncProgramming hashtag#Coding hashtag#LearnToCode hashtag#100DaysOfCode
To view or add a comment, sign in
-
-
TypeScript beyond the basics — the patterns that actually matter in large codebases. 🔷 Most engineers know types. Fewer know how to design with them. 🧬 Generics are not just "flexible types" They preserve the relationship between input and output. any → tells TypeScript to stop checking T → track this, enforce this, follow it everywhere These are fundamentally different contracts. 🔒 Generic constraints = compile-time safety < function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } > You literally cannot pass a key that doesn't exist on the object. Not a runtime check. A compile-time guarantee. 🛠️ Utility types — type transformers, not just shortcuts ✅ Partial<T> → teams override only what they need ✅ Readonly<T> → shared config nobody can accidentally mutate ✅ Omit<T, K> → hide internals from consuming teams ✅ Pick<T, K> → expose only what teams should see Compose them for real power 👇 < type TeamConfig = Readonly<Omit<AppConfig, 'debug' | 'timeout'>>; /> 🔍 infer — extract types from inside other types </ type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; > Not just checking types. Pattern matching on them. Like destructuring — but at the type level. 🎯 The real payoff — a fully type-safe API client Where the route name drives the payload AND the response type automatically. ❌ Wrong route → compile error ❌ Wrong payload → compile error ❌ Wrong property on response → compile error Zero any. Zero guessing. Full autocomplete for every team consuming your library. 💪 Follow along — sharing one deep dive at a time. 🚀 #TypeScript #FrontendEngineering #PlatformEngineering #WebDevelopment #JavaScript
To view or add a comment, sign in
-
Stop misusing JavaScript array methods. Small choices like this quietly shape code quality. One of the most common clean-code mistakes I see is using `forEach()` when the real intention is transformation. If your goal is to create a new array from existing data, `map()` is the right tool. `map()` returns a new array. It keeps your logic functional and predictable. It communicates intent clearly: “I am transforming data.” That clarity improves readability and long-term maintainability. `forEach()`, on the other hand, is built for side effects—logging, DOM updates, triggering external behavior. It does not return a new array. When you push into another array inside `forEach()`, you’re working against the language instead of with it. A simple rule of thumb: * If you’re creating a new array → use `map()` * If you’re performing side effects → use `forEach()` * If you’re filtering → use `filter()` instead of manual conditions Clean code isn’t about writing more lines. It’s about choosing the right abstraction for the job. Intentional developers let method names express meaning. So be honest—are you team `map()`, or still reaching for `forEach()` when transforming data? #JavaScript #CleanCode #FrontendDevelopment #WebEngineering #SoftwareCraftsmanship #CodeQuality #ReactJS
To view or add a comment, sign in
-
-
#ProfessionalDevelopment #FrontendBasics Question: Explain the difference in hoisting between var, let, and const Answer: In JavaScript, var, let, and const are used to declare variables, but they differ in scope, reassignment behavior, and how they behave during hoisting. The var keyword declares a variable that is either function-scoped or globally scoped, depending on where it is defined, and it can be reassigned. The let keyword declares a block-scoped variable that can also be reassigned. The const keyword declares a block-scoped variable that cannot be reassigned and must be initialized at the time of declaration. Hoisting refers to JavaScript’s behavior of processing declarations before executing code. While it may appear that declarations are moved to the top of their scope, what actually happens is that memory is allocated for variables and functions during the creation phase of execution. Variables declared with var are hoisted and initialized with a default value of undefined. This means they can be accessed before their declaration without throwing an error, although the value will be undefined. In contrast, variables declared with let and const are also hoisted, but they are not initialized. Instead, they exist in a state known as the Temporal Dead Zone (TDZ) from the start of their scope until their declaration is encountered. Attempting to access them during this period results in a runtime error. Understanding these differences helps developers write predictable code and avoid bugs related to accessing variables before initialization. Question answers come from research, rewrites, and refinement. Reference: https://lnkd.in/eYf-cKn8 Additional research: MDN Web Docs, Wikipedia, and general web research Happy coding, y’all! 👨🏿💻 #javascript #frontend #frontenddeveloper #webdevelopment #softwareengineer #softwaredevelopment #coding #programming #developers #devcommunity #buildinpublic #learninpublic #careerdevelopment #techcareers
To view or add a comment, sign in
-
-
𝗟𝗶𝗳𝘁𝗶𝗻𝗴 𝗦𝘁𝗮𝘁𝗲 𝗨𝗽 𝗖𝗮𝗻 𝗖𝗿𝗲𝗮𝘁𝗲 𝗠𝗼𝗿𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺𝘀 𝗧𝗵𝗮𝗻 𝗜𝘁 𝗦𝗼𝗹𝘃𝗲𝘀 Classic advice: "𝘛𝘸𝘰 𝘴𝘪𝘣𝘭𝘪𝘯𝘨𝘴 𝘯𝘦𝘦𝘥 𝘵𝘩𝘦 𝘴𝘢𝘮𝘦 𝘥𝘢𝘵𝘢? 𝘓𝘪𝘧𝘵 𝘴𝘵𝘢𝘵𝘦 𝘵𝘰 𝘱𝘢𝘳𝘦𝘯𝘵." ✅ Parent holds: [searchTerm, setSearchTerm] <SearchForm search={searchTerm} onChange={setSearchTerm} /> <ResultsList search={searchTerm} /> 𝗪𝗼𝗿𝗸𝘀 𝗴𝗿𝗲𝗮𝘁. 𝗨𝗻𝘁𝗶𝗹: Parent now coordinates: • Search + Results • Filters + Results • Pagination + Results • Theme + Every component Parent becomes a 400+ line coordination layer. Re-renders everything. Prop drilling nightmare. 𝗕𝗲𝘁𝘁𝗲𝗿 𝗮𝗽𝗽𝗿𝗼𝗮𝗰𝗵𝗲𝘀 𝗲𝘅𝗶𝘀𝘁: ✅ Option 1: Local duplication (cheaper than sync) // SearchForm const [search, setSearch] = useState('') // ResultsList const [search, setSearch] = useState('') ✅ Option 2: Targeted Context (no drilling) const SearchContext = createContext() <SearchContext.Provider value={searchTerm}> <SearchForm /> <ResultsList /> </SearchContext.Provider> ✅ Option 3: Zustand (zero boilerplate) const useSearchStore = create((set) => ({ search: '', setSearch: (value) => set({ search: value }) })) 𝗔 𝘀𝗶𝗺𝗽𝗹𝗲 𝘄𝗮𝘆 𝘁𝗼 𝗱𝗲𝗰𝗶𝗱𝗲: • Only one component needs it? → Local state • 2-3 related components? → Context slice • App-wide? → Global store (Zustand/Jotai) • Everything in one parent? → Usually a sign to rethink What feels "simple" in the moment (lifting up) can quietly make your app harder to change later. Next time you reach for the parent, ask: 𝘞𝘩𝘰 𝘳𝘦𝘢𝘭𝘭𝘺 𝘰𝘸𝘯𝘴 𝘵𝘩𝘪𝘴 𝘴𝘵𝘢𝘵𝘦? #React #StateManagement #JavaScript #WebDev #FrontendArchitecture #ReactHooks #Programming
To view or add a comment, sign in
-
Day 67 of me reading random and basic but important dev topicsss..... Today I read about the Advanced JavaScript Range Properties & Methods..... Yesterday, I looked at the fundamentals of creating a Range in the DOM. Today, I explored the properties and convenience methods that make traversing and building these ranges highly efficient. When integrating raw DOM logic into frameworks like React, knowing these native shortcuts saves us from writing manual, bug-prone offset calculations. Core Range Properties: When we inspect a Range object, it gives us crucial contextual data: * startContainer / startOffset: The exact node and position where the range begins. * endContainer / endOffset: The node and position where the range ends. * collapsed: A boolean. true if the start and end are at the exact same point (think of a blinking text cursor with no characters highlighted). * commonAncestorContainer: The deepest parent element that fully wraps the entire range. (Incredibly useful for validating if a user's selection is contained within a specific UI component!). Pro Methods (Skip the math!): Instead of calculating exact indexes with setStart and setEnd, you can leverage semantic methods: * setStartBefore(node) / setStartAfter(node): Drops the boundary right outside a target node. * selectNode(node): Creates a range that encompasses the entire node, including its outer HTML tags. * selectNodeContents(node): Selects only the inside of the node......perfect for instantly capturing all the text inside a <div> or <p>. * collapse(toStart): Instantly shrinks the range to just its starting or ending cursor point. Keep Learning!!!!!! #JavaScript #WebDevelopment #DOM #FrontendDev
To view or add a comment, sign in
-
-
I’ve decided to stop just "watching" and start "doing." Today was all about getting deep into the JavaScript fundamentals that actually make a difference in real-world projects. It’s one thing to see a tutorial, but it’s another thing to actually write the logic and see it work! Here is what my practice session looked like today: ✅ Modernizing my Code: Switched to const and let for better safety and started using Arrow Functions to keep my logic concise and readable. ✅ The Power of Clean Data: I finally grasped how Object & Array Destructuring saves so much time when pulling out specific data. No more repetitive code! ✅ The Magic of Three Dots (...): Used the Spread Operator to handle arrays and pass parameters into functions effortlessly. ✅ Object Control: Explored how to manage objects using Keys, Values, and Entries. I also learned about Object.freeze and Object.seal—essential for keeping data secure. ✅ Bug Prevention: Started using Optional Chaining (?.). This is a total game-changer for avoiding those annoying "cannot read property" errors when dealing with nested data. ✅ Smart Looping: Practiced the difference between for...in and for...of to make sure I’m always using the right tool for the job. Every line of code I write feels like I'm building a stronger bridge toward becoming a Full-Stack Developer. Consistency is the key! 🔑 #JavaScript #WebDev #CodingJourney #LearningToCode #Frontend #Programming
To view or add a comment, sign in
-
-
A widely recommended webpack externals fix for the ws library has been silently breaking WebSocket data in Electron apps since 2017. No errors. No warnings. Frames just disappeared inside the library. I was building Margay, an Electron app forked from a 15k-star open source project. Remote WebUI mode — access from a browser on your local network — showed a blank screen after login. Desktop mode worked perfectly. The WebSocket connection looked completely healthy. Handshake succeeded. Authentication passed. But zero data messages arrived. Alive on paper, dead in practice. My instinct as a 30-year software veteran: stay at the application layer. Check configs, review auth flow, look for race conditions. That's what any experienced developer would do. After 15 rounds of dead ends, two AI agents (Claude Code + Codex) in a Ralph-Lisa Loop wanted to go deeper — TCP-level monitoring, ws library internals. I pushed back. They went back to the application layer as I asked, proved it clean with evidence, then went deeper anyway. What they found: 12 TCP frames entering the socket, 0 firing ws.on('message'). A silent crash inside the ws library's native code path — caused by that widely copy-pasted webpack externals fix. The ws library has an undocumented 32-byte threshold. Frames under 32 bytes use a JS fallback (heartbeats: 6 bytes, works fine). Frames over 32 bytes use a native C++ module (data messages: 100+ bytes, crashes silently). Perfect camouflage. 25 rounds. 4 lines of fix. A bug hiding in plain sight for 8 years. This is why I built the Ralph-Lisa Loop — a dual-agent workflow where one AI investigates and another validates each step. It's not that two AIs are smarter than one. It's that the structure enforces systematic elimination that humans resist when the answer requires leaving their comfort zone. This is the second real-world case where RLL handled complex, multi-layer work that goes well beyond simple code generation — from forking a 15k-star Electron app to tracing a silent failure across application, protocol, and library layers. The pattern holds: when debugging crosses layer boundaries, dual-agent consensus catches what single-agent workflows miss. Full writeup: https://lnkd.in/gBxKg5BY GitHub: https://lnkd.in/gRPWeDz9 #AIProgramming #WebSocket #Debugging #DeveloperTools #AIAgents
To view or add a comment, sign in
More from this author
Explore related topics
- How to Achieve Clean Code Structure
- How to Refactor Code Thoroughly
- How To Prioritize Clean Code In Projects
- Importance of Code Deletion in Software Projects
- Importance of Removing Dead Code in Software Development
- Managing Dependencies For Cleaner Code
- How to Add Code Cleanup to Development Workflow
- Why Software Engineers Prefer Clean Code
- GitHub Code Review Workflow Best Practices
- Key Skills for Writing Clean Code
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development