Best Practices for Code Structure and Semantics

Explore top LinkedIn content from expert professionals.

  • View profile for Yangshun Tay
    Yangshun Tay Yangshun Tay is an Influencer

    AI Frontend Engineer • GreatFrontEnd • Ex-Meta Staff Engineer • Creator Docusaurus 2 & Blind 75

    113,931 followers

    🏆 How GreatFrontEnd's code base is structured 🏆 Some practices we use on a semi-large code base like greatfrontend.com → Typesafety: We use TypeScript. Code with types eliminate an entire class of bugs and is easier to read and maintain → Linting and formatting: We use Prettier and ESLint with a set of opinionated lint rules. Our lint rules enforce import order, object keys order, enable fix + format on save in IDE → Monorepo: We use Turborepo with a few packages – app, questions, guidebooks, lint rules, etc. → Package management: We use pnpm, which is a great package manager → UI components: A11y is hard, so we use headless components (Radix UI) that come with built-in behavior and a11y and customize styling. Alternatives include Headless UI, Ark UI and Base UI → Routing: Next.js is our choice of meta frameworks. The `/app` directory is for routing only. All UI code and data fetching code are in separate directories. That way we can move/rename routes easily without affecting downstream files → Data fetching: We use tRPC as a typesafe data fetching approach → Statically generated atomic CSS: The easiest way to have a scalable CSS file size in large code bases. Use libraries like Tailwind and StyleX → Z-index list: Z-index wars is the most commonly fought war in front end development. We defined a list of z-indices and use them for global-level elements like dialogs, popovers, tooltips, etc. This is a tricky topic so I might go deeper into it another day. → Content: All content lives in the repository and not in an external CMS. That way we can ensure the same content across development, staging, and production environments. → Util libs: We standardized on utility libraries like Lodash, date-fns, hooks (usehooks-ts) → Separate product code vs common code: We have clear separation of common code vs product-specific code. Design system components should not embed business logic. → Presentation vs Business: Split components according to presentational vs business logic (frequently called small vs dumb but I don't like the word "dumb). That way it's easier to test them → File organization: Modularize and co-locate code by products/features/verticals. All code related to auth, marketing, purchases, blog, etc. are in their own directories → State management: For most apps, most state is server-fetched data, which Tanstack Query does an excellent job in managing. For local state, reach for context before using 3rd party libs like Redux, Zustand, Jotai → Performance: Optimize when you encounter perf problems. No need for useMemo, useCallback yet. The React compiler will help with this in future anyway #react #nextjs #tailwindcss #javascript #typescript #supabase #prisma #eslint

  • View profile for Julien Chaumond

    CTO at Hugging Face

    273,686 followers

    Code is the product. How do you prevent a 1M+ LoC Python library, built by thousands of contributors, from collapsing under its own weight? In transformers, we do it with a set of explicit software engineering tenets. With Pablo Montalvo, Lysandre Debut, Pedro Cuenca and Yoni Gozlan, we just published a deep dive on the principles that keep our codebase hackable at scale. What’s inside: – The Tenets We Enforce: From One Model, One File to Standardize, Don't Abstract, these are the rules that guide every PR. – "Modular Transformers": How we used visible inheritance to cut our effective maintenance surface by ~15× while keeping modeling code readable from top to bottom. – Pluggable Performance: A standard attention interface and config-driven tensor parallelism mean semantics stay in the model while speed (FlashAttention, community kernels, TP sharding) is a configurable add-on, not a code rewrite. This matters for anyone shipping models, contributing to OSS, or managing large-scale engineering projects. It’s how we ensure a contribution to transformers is immediately reusable across the ecosystem (vLLM, ggml, SGLang, etc.). Read more on the Hugging Face blog

  • View profile for 🎯  Ming "Tommy" Tang

    Director of Bioinformatics | Cure Diseases with Data | Click “Contact Info” to grab my new book “What they do not teach you in Bioinformatics” | >150K followers, >30M impressions annually across social platforms

    72,261 followers

    You inherit someone else’s bioinformatics code. No comments. No structure. Variable names like x1, foo, temp2. And now it’s your problem. Let’s talk about that experience—and how to do better. 1/ Ever opened someone’s script and felt instant regret? No README No comments Hard-coded paths Copy-pasted blocks No functions You’re not alone. Code without structure is like a freezer full of unlabelled tubes. Sure, it runs. But good luck figuring out what anything does. 3/ Bad practices hurt you the most. Even if you wrote the code. You: “I’ll remember this later.” Also you (6 weeks later): “Who wrote this garbage?” Still you. 4/ On the flip side: Well-structured code feels like a gift. Functions are defined. Comments explain the logic. Each section is modular. You can re-use it. You can trust it. 5/ Here’s what I’ve learned from writing and inheriting messy code: Bad code punishes future you. Good code rewards collaborators. 6/ What are some good coding practices in bioinformatics? Use clear variable names Comment your logic, not just what each line does Break repetitive steps into functions Keep a README and usage example Use relative paths and config files 7/ Avoid this: x1 <- read.table("data.txt") temp2 <- x1[which(x1[,3] > 10), ] Prefer this: expression_data <- read.table("data.txt", header=TRUE) high_expr <- subset(expression_data, expression > 10) Make it obvious what’s happening. 8/ Turn repeated blocks into functions: filter_by_threshold <- function(data, column, threshold) { subset(data, data[[column]] > threshold) } Now your code is DRY (Don’t Repeat Yourself) and reusable. 9/ Keep outputs organized: mkdir -p results/qc mkdir -p results/plots If your outputs are sprinkled across your desktop, it’s time to rethink. 10/ Bonus: write a run_pipeline.sh that chains all your steps. Use snakemake or nextflow if it gets too big. Even a bash script with clear comments beats scattered commands. 11/ Want to learn how to write better code? Read other people’s good code. You’ll learn tricks no tutorial teaches. 12/ Good code is a form of respect. For yourself. For your collaborators. For the person who inherits your project next. Write like someone else has to read it. Because they will. 13/ Bioinformatics isn’t just about solving problems. It’s about communicating how you solved them. Your code is your paper in progress. Write it like you’re proud of it. I hope you've found this post helpful. Follow me for more. Subscribe to my FREE newsletter chatomics to learn bioinformatics https://lnkd.in/erw83Svn

  • View profile for Robert Sanderson

    Senior Director for Digital Cultural Heritage and Fractional Associate University Librarian for Digital Strategy at Yale University; working to harmonize and provide access to high-quality data in a human-oriented way

    3,546 followers

    Ontology Design Patterns (Part 3): *Naming Things* Naming your predicates and classes (collectively terms) in the ontology is both an art and a science. The semantics associated with the term are the important thing, however the uncomfortable truth is that most developers or even data modelers will not read your carefully written scope notes, they'll just make assumptions based on the name and get back to coding. So, much like the (revised, thank you commenters!) principle of "Anticipate JSON-LD as the serialization", this is all about Developer Experience or Data Usability at the ontology level. If your names are easy to remember, consistent and easy to use in code, then your data has a step up before any instances are even created. Naming Rules I try to follow: * Most importantly, Be Consistent! Use the same naming conventions throughout the ontology. Every exception is a bug waiting to happen! * Names should be readable and in English. For better or worse, English is the language of computer science and, well, you have to pick a language for the name. Some ontologies instead use only numbers (such as RDA, wikidata, etc.) to avoid a linguistic bias, but this just makes it equally *unusable* for everyone. * Don't include numbers in the names at all, as it makes them impossible to remember. * Per basically all best practice guides, use camelCase for predicates and PascalCase for classes. * Do not use - in a name as then you can't use it in code (Human-MadeObject will be seen as Human - MadeObject) even though it's legal in URIs * Reserve _ as the first character of a term for internal use or extensions. This makes your internal fields clear to everyone, even if they're shared outside your organization. * As all terms must have unique names, if you find a situation where you want to use the same name as an existing term, then is it actually just the same term? For example, if you have 5 different "partOf" predicates for different classes, and you want to name them all "partOf" ... it's more likely that you just need an ancestor class in the hierarchy that defines the relationship for all of them. * Make a dictionary of the components used within the terms. e.g. do you use "id" or "identifier"? * Ensure the inverse relationship name directly reflects the relationship. If the relationship is (agent) "created" (object), then the inverse should be (object) "createdBy" (agent) not "author" or "maker". * Decide at the beginning of the project whether to include is/was/has/had (etc) at the beginning of term names. Is it "isPartOf" or just "partOf"? * Decide if abbreviations are all capitals or only the first character. Is it "hasXMLContent" or "hasXmlContent"? (Note that Linked Art doesn't follow all these rules as we inherited the ontology from the existing CIDOC-CRM specification. We did what we could to normalize them in the JSON-LD context, but this results in a pain point when you try to translate between JSON-LD and SPARQL queries.)

  • View profile for Kasra Jadid Haghighi

    Senior Software Developer | .NET

    229,535 followers

    Best Practices for Writing Clean and Maintainable Code One of the worst headaches is trying to understand and work with poorly written code, especially when the logic isn’t clear. Writing clean, maintainable, and testable code—and adhering to design patterns and principles—is a must in today’s fast-paced development environment. Here are a few strategies to help you achieve this: 1. Choose Meaningful Names: Opt for descriptive names for your variables, functions, and classes to make your code more intuitive and accessible. 2. Maintain Consistent Naming Conventions: Stick to a uniform naming style (camelCase, snake_case, etc.) across your project for consistency and clarity. 3. Embrace Modularity: Break down complex tasks into smaller, reusable modules or functions. This makes both debugging and testing more manageable. 4. Comment and Document Wisely: Even if your code is clear, thoughtful comments and documentation can provide helpful context, especially for new team members. 5. Simplicity Over Complexity: Keep your code straightforward to enhance readability and reduce the likelihood of bugs. 6. Leverage Version Control: Utilize tools like Git to manage changes, collaborate seamlessly, and maintain a history of your code. 7. Refactor Regularly: Continuously review and refine your code to remove redundancies and improve structure without altering functionality. 8. Follow SOLID Principles & Design Patterns: Applying SOLID principles and well-established design patterns ensures your code is scalable, adaptable, and easy to extend over time. 9. Test Your Code: Write unit and integration tests to ensure reliability and make future maintenance easier. Incorporating these tips into your development routine will lead to code that’s easier to understand, collaborate on, and improve. #CleanCode #SoftwareEngineering #CodingBestPractices #CodeQuality #DevTips

  • View profile for Mayank A.

    Follow for Your Daily Dose of AI, Software Development & System Design Tips | Exploring AI SaaS - Tinkering, Testing, Learning | Everything I write reflects my personal thoughts and has nothing to do with my employer. 👍

    185,888 followers

    Software Design Principles Great software isn't just about making things work, it's about creating systems that are maintainable, scalable, and resilient. These fundamental design principles guide developers toward writing better code. 1./ 𝐊𝐈𝐒𝐒 (𝐊𝐞𝐞𝐩 𝐈𝐭 𝐒𝐢𝐦𝐩𝐥𝐞, 𝐒𝐭𝐮𝐩𝐢𝐝) ➟ The most elegant solutions are often the simplest. ➟ Avoid unnecessary complexity, keep code clear and concise, and focus on essential features. Remember that code is read far more often than it's written. 2./ 𝐃𝐑𝐘 (𝐃𝐨𝐧'𝐭 𝐑𝐞𝐩𝐞𝐚𝐭 𝐘𝐨𝐮𝐫𝐬𝐞𝐥𝐟) ➟ Every piece of knowledge in a system should have a single, unambiguous representation. 3./ 𝐘𝐀𝐆𝐍𝐈 (𝐘𝐨𝐮 𝐀𝐢𝐧'𝐭 𝐆𝐨𝐧𝐧𝐚 𝐍𝐞𝐞𝐝 𝐈𝐭) ➟ Resist implementing features "just in case." ➟ Build what's needed today. 4./ 𝐒𝐎𝐋𝐈𝐃 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞𝐬 the backbone of object-oriented design: ➟ Single Responsibility - Classes should do one thing well ➟ Open/Closed - Open for extension, closed for modification ➟ Liskov Substitution - Subtypes must be substitutable for their base types ➟ Interface Segregation - Many specific interfaces beat one general interface ➟ Dependency Inversion - Depend on abstractions, not concrete implementations 5./ 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞 𝐨𝐟 𝐋𝐞𝐚𝐬𝐭 𝐀𝐬𝐭𝐨𝐧𝐢𝐬𝐡𝐦𝐞𝐧𝐭 ➟ Software should behave as users expect. ➟ Consistency in terminology, conventions, and error messages creates intuitive experiences. 6./ 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞 𝐨𝐟 𝐌𝐨𝐝𝐮𝐥𝐚𝐫𝐢𝐭𝐲 ➟ Well-defined, independent modules make systems easier to understand, maintain, and test. 7./ 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞 𝐨𝐟 𝐀𝐛𝐬𝐭𝐫𝐚𝐜𝐭𝐢𝐨𝐧 ➟ Hide implementation details to reduce cognitive load. ➟ Users of your code shouldn't need to know how it works internally, just how to use it. 8./ 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞 𝐨𝐟 𝐄𝐧𝐜𝐚𝐩𝐬𝐮𝐥𝐚𝐭𝐢𝐨𝐧 ➟ Protect the internal state of objects from external manipulation. ➟ This creates more robust systems by preventing unexpected side effects. 9./ 𝐏𝐫𝐢𝐧𝐜𝐢𝐩𝐥𝐞 𝐨𝐟 𝐋𝐞𝐚𝐬𝐭 𝐊𝐧𝐨𝐰𝐥𝐞𝐝𝐠𝐞 (𝐋𝐚𝐰 𝐨𝐟 𝐃𝐞𝐦𝐞𝐭𝐞𝐫) ➟ Components should have limited knowledge of other components. ➟ This "need-to-know basis" approach creates more modular, flexible systems. 10./ 𝐋𝐨𝐰 𝐂𝐨𝐮𝐩𝐥𝐢𝐧𝐠 & 𝐇𝐢𝐠𝐡 𝐂𝐨𝐡𝐞𝐬𝐢𝐨𝐧 ➟ Minimize dependencies between modules while ensuring each module has a clear, unified purpose. ➟ This balance makes systems more maintainable and adaptable. You’d probably agree, It's easy to nod along with design principles when reading them, but much harder to catch when drifting away from them in real code. That's where tools like CodeRabbit can be valuable. During pull requests, it identifies potential issues that developers might overlook, such as unnecessary complexity or signs of tight coupling, without being intrusive or slowing down the development process. Understand, these tools don't replace human judgment but provide an additional layer of verification that can help maintain code quality over time.👊 coderabbit.ai

  • View profile for Arslan Ahmad

    Author of Bestselling ‘Grokking’ Series on System Design, Software Architecture & Coding Patterns | Founder DesignGurus.io

    191,735 followers

    𝗖𝗹𝗲𝗮𝗻 𝗰𝗼𝗱𝗲 𝗶𝘀𝗻’𝘁 𝗷𝘂𝘀𝘁 𝗮𝗯𝗼𝘂𝘁 𝘄𝗿𝗶𝘁𝗶𝗻𝗴 𝗰𝗼𝗿𝗿𝗲𝗰𝘁 𝗰𝗼𝗱𝗲... It’s about writing code that’s easy to read, change, and maintain. Here are 𝟲 𝗲𝘀𝘀𝗲𝗻𝘁𝗶𝗮𝗹 𝗿𝘂𝗹𝗲𝘀 to help you master clean coding: 🔹 𝗦𝗘𝗣𝗔𝗥𝗔𝗧𝗜𝗢𝗡 𝗢𝗙 𝗖𝗢𝗡𝗖𝗘𝗥𝗡𝗦 (𝗦𝗢𝗖) Best for: Organizing your codebase into logical units ✅ Split responsibilities across modules or layers ✅ Each component should do only one thing well ✅ Makes testing and debugging easier 🔹 𝗗𝗢𝗖𝗨𝗠𝗘𝗡𝗧 𝗬𝗢𝗨𝗥 𝗖𝗢𝗗𝗘 (𝗗𝗬𝗖) Best for: Collaboration and long-term maintainability ✅ Write code for your future self and teammates ✅ Add clear, concise comments for complex logic ✅ Use docstrings, READMEs, and code annotations 🔹 𝗗𝗢𝗡’𝗧 𝗥𝗘𝗣𝗘𝗔𝗧 𝗬𝗢𝗨𝗥𝗦𝗘𝗟𝗙 (𝗗𝗥𝗬) Best for: Avoiding duplicate logic and bugs ✅ Reuse code via functions, modules, or utilities ✅ Centralize logic so one change updates all instances ✅ Easier to scale and refactor 🔹 𝗞𝗘𝗘𝗣 𝗜𝗧 𝗦𝗜𝗠𝗣𝗟𝗘, 𝗦𝗧𝗨𝗣𝗜𝗗 (𝗞𝗜𝗦𝗦) Best for: Writing code that others (and you) understand ✅ Prioritize clarity over cleverness ✅ Simple logic is easier to debug and extend ✅ If it’s hard to read, it’s probably wrong 🔹 𝗧𝗘𝗦𝗧 𝗗𝗥𝗜𝗩𝗘𝗡 𝗗𝗘𝗩𝗘𝗟𝗢𝗣𝗠𝗘𝗡𝗧 (𝗧𝗗𝗗) Best for: Building reliable and bug-free systems ✅ Start with a failing test before writing code ✅ Write just enough code to make it pass ✅ Refactor later with confidence 🔹 𝗬𝗢𝗨 𝗔𝗜𝗡’𝗧 𝗚𝗢𝗡𝗡𝗔 𝗡𝗘𝗘𝗗 𝗜𝗧 (𝗬𝗔𝗚𝗡𝗜) Best for: Avoiding overengineering ✅ Build only what’s needed right now ✅ Future-proofing often leads to waste and complexity ✅ Less code = fewer bugs 📌 Clean Code Summary SOC → Modular code with clear responsibilities DYC → Self-explanatory code + solid documentation DRY → Reuse logic, reduce redundancy KISS → Keep it simple and readable TDD → Let tests guide your design YAGNI → Build what’s necessary today, not tomorrow 💬 What’s your personal golden rule for clean code? References: 📌 Grokking SOLID Design Principles: https://lnkd.in/gHFnkPh8 📌 Grokking Design Patterns for Engineers and Managers: https://lnkd.in/gHYiMuEh #systemdesign #coding #interviewtips

  • View profile for Brij Kishore Pandey

    AI Architect & Engineer | Agentic systems, RAG, AI infrastructure, Data Engineering | 738K+ LinkedIn, 294K+ Instagram | Newsletter for 250K AI builders

    740,411 followers

    Clean code isn't just about readability —it's about creating maintainable, scalable solutions that stand the test of time. When we prioritize readability, simplicity, and thoughtful architecture, we're not just making our lives easier; we're creating value for our teams and organizations. A few principles that have made the most significant difference in my work over years: • Meaningful naming that reveals intent • Functions that do one thing exceptionally well • Tests that serve as documentation and safety nets • Consistent formatting that reduces cognitive load The greatest insight I've gained is that clean code is fundamentally an act of communication—with future developers, our teammates, and even our future selves. The time invested upfront pays dividends during maintenance, debugging, and onboarding. What clean code practices have transformed your development experience? I'd love to hear about the principles that guide your work. Image Credit - Keivan Damirchi

  • View profile for Aishwarya Naresh Reganti

    Founder & CEO @ LevelUp Labs | Human-First AI Transformation For Your Enterprise

    131,015 followers

    😅 The biggest AI coding question today: how do you get to production without shipping vibe coded slop? A lot of developers now understand that AI can help them move fast. You can vibe code a prototype, generate a feature quickly, and get a working draft in minutes. But the harder question is, how do you make sure the code actually stands the test of time? This is exactly what Mihail Eric covered in our internal Chai & AI community session last week. Mihail teaches the "The Modern Software Developer" course at Stanford, is Head of AI at Monaco, and was also a colleague of mine back at Alexa. In the session, he introduced his RePPIT framework for using AI to ship production quality code. RePPIT breaks down the coding process into five deliberate steps: (Re)search, (P)ropose, (P)lan, (I)mplement, and (T)est. A few ideas from the RePPIT framework, although I’d recommend reading the whole the whole article we wrote around the session (linked below): ⛳ Research the codebase: Before asking AI to implement anything, first ask it to understand the architecture, file layout, dependencies, design decisions, and existing patterns. This keeps the model grounded in the actual codebase. ⛳ Propose solutions: Instead of jumping straight into code, ask the model to generate a couple of different implementation paths with tradeoffs, validation plans, and open questions. This is where you, as the developer, make the judgment call. ⛳ Plan the chosen solution: Once you pick a direction, turn it into a proper design doc. This helps define what’s in scope, what’s out of scope, what files need to change, and how the feature should be tested. ⛳ Implement the plan: Only after the research, proposal, and planning steps should the model start writing code. At this point, it has enough context to avoid guessing its way through the implementation. ⛳ Test what got built: Don’t let the same model instance blindly approve its own work. Use a fresh context or a different model to review, test, and critique the implementation before you trust it. I think a lot of this boils down to strong context engineering. It was also super useful to walk through a concrete example, which you can see in the article. Article: https://lnkd.in/gG9uF6kC Mihail also runs an incredibly cool course at Stanford as well as on Maven. You can find links to both below!

  • View profile for Alexandre Zajac

    SDE & AI @Amazon | Building Hungry Minds to 1M+ | Daily Posts on Software Engineering, System Design, and AI ⚡

    162,108 followers

    The 10 Rules NASA Swears By to Write Bulletproof Code: 0. Restrict to simple control flow ↳ No goto, setjmp, longjmp, or recursion. Keep it linear and predictable. This ensures your code is easily verifiable and avoids infinite loops or unpredictable behavior. 1. Fixed loop bounds ↳ Every loop must have a statically provable upper bound. No infinite loops unless explicitly required (e.g., schedulers). This prevents runaway code and ensures bounded execution. 2. No dynamic memory allocation after initilization ↳ Say goodbye to malloc and free. Use pre-allocated memory only. This eliminates memory leaks, fragmentation, and unpredictable behavior. 3. Keep functions short ↳ No function should exceed 60 lines. Each function should be a single, logical unit that’s easy to understand and verify. 4. Assertion density: 2 per function ↳ Use assertions to catch anomalous conditions. They must be side-effect-free and trigger explicit recovery actions. This is your safety net for unexpected errors. 5. Declare data at the smallest scope ↳ Minimize variable scope to prevent misuse and simplify debugging. This enforces data hiding and reduces the risk of corruption. 6. Check all function returns and parameters ↳ Never ignore return values or skip parameter validation. This ensures error propagation and prevents silent failures. 7. Limit the preprocessor ↳ Use the preprocessor only for includes and simple macros. Avoid token pasting, recursion, and excessive conditional compilation. Keep your code clear and analyzable. 8. Restrict pointer use ↳ No more than one level of dereferencing. No function pointers. This reduces complexity and makes your code easier to analyze. 9. Compile with all warnings enabled ↳ Your code must be compiled with zero warnings in the most pedantic settings. Use static analyzers daily to catch issues early. Some of these rules can be seen as hard to follow, but you can't allow room for error when lives are at stake. Which ones are you still applying? #softwareengineering #systemdesign ~~~ 👉🏻 Join 46,001+ software engineers getting curated system design deep dives, trends, and tools (it's free): ➔ https://lnkd.in/dCuS8YAt ~~~ If you found this valuable: 👨🏼💻 Follow Alexandre Zajac 🔖 Bookmark this post for later ♻️ Repost to help someone in your network

Explore categories