Webbo3 Data Analysis Bootcamp · Web Development Module · Lesson 1
Dev Workflow and Tools: Emmet, Prettier, ESLint, Browser DevTools, and Professional Git Practices
A practical lesson covering the essential tools and workflows that separate hobbyist coding from professional development: rapid markup with Emmet, consistent formatting with Prettier, error catching with ESLint, debugging with browser DevTools, and team collaboration with Git.
Writing code that works is only half the job. Writing code that is readable, maintainable, properly formatted, and tracked through version control is what makes you employable. In a professional environment, no one writes raw HTML tag by tag, hunts for missing semicolons by eye, or deploys code without reviewing it through a pull request. The tools and workflows in this lesson are the infrastructure of modern software development. They are not optional extras. They are the standard operating procedure at every company that ships software, from one-person startups to teams of five hundred engineers. Master them now, and every project you build from this point forward will be faster to write, easier to debug, and safer to change.
1. Emmet Shortcuts in VS Code
Emmet is a shortcut system built into VS Code that expands abbreviations into full HTML and CSS structures. It is not a separate program. It is already installed and active in every HTML, CSS, and JavaScript file you open. Learning Emmet is the single fastest way to increase your coding speed, because it eliminates the repetitive typing that consumes most of a developer's time.
The HTML boilerplate. Type an exclamation mark in an empty HTML file and press Tab or Enter. Emmet expands it into a complete HTML5 document structure with the doctype, html, head, body, and meta viewport tags. This one shortcut saves you from typing thirty lines of boilerplate every time you start a new file.
Creating elements with content. Type h1{Welcome to Webbo3} and press Tab. Emmet expands it to . The curly braces wrap the text inside the element. This works for any tag: Welcome to Webbo3
p{This is a paragraph}, a{Click here}, div{Container content}.
Nesting with the greater-than symbol. The > operator creates parent-child relationships. Type ul>li*3 and press Tab. Emmet expands it to an unordered list with three list items. The asterisk * is multiplication. It creates multiple instances of the preceding element. Type nav>ul>li*5>a{Link $} and you get a navigation bar with five links, each labeled Link 1 through Link 5 automatically. The dollar sign $ is an auto-incrementing number.
IDs and classes. Use the hash symbol for IDs and the dot for classes, exactly like CSS selectors. div#main expands to . div.container expands to . section.hero.banner expands to with multiple classes. You can combine them: div#header.container.flex gives you an element with an ID and two classes.
Grouping with parentheses. Parentheses let you group complex structures without ambiguity. Type (div>h2{Title})+(div>p{Description}) and Emmet creates two sibling divs, one containing an h2 and the other containing a paragraph. Without the parentheses, Emmet might nest the second div inside the first depending on operator precedence.
CSS abbreviations. Emmet works in CSS files too. Type m20 and press Tab to get margin: 20px;. Type p10 for padding: 10px;. Type w100 for width: 100px;. Type c#333 for color: #333;. Type bg#f4f4f4 for background-color: #f4f4f4;. For flexbox, d:f becomes display: flex;, ai:c becomes align-items: center;, and jc:sb becomes justify-content: space-between;. These shortcuts save seconds per property, which compounds into hours over a week of development.
Enabling Emmet for other file types. By default, Emmet works in HTML and CSS files. If you want it in JavaScript or PHP files, open VS Code Settings with Ctrl + ,, search for Emmet: Include Languages, and add mappings like javascript to javascriptreact or php to html. This is useful when you are writing JSX in React or embedding HTML inside PHP templates.
2. Prettier for Code Formatting
Prettier is an opinionated code formatter. Opinionated means it makes decisions for you. It decides how many spaces to indent, where to break lines, whether to use single or double quotes, and where to place semicolons. You do not debate these decisions. You install Prettier, configure it once, and let it enforce consistency across every file in your project. Consistency matters because reading code is harder than writing it, and inconsistent formatting forces your brain to switch parsing modes every time you open a different file.
Installing Prettier in VS Code. Open the Extensions panel with Ctrl + Shift + X, search for Prettier - Code: formatter by Esben Petersen, and click Install. Once installed, Prettier can format HTML, CSS, JavaScript, TypeScript, JSON, Markdown, and many other languages. You do not need separate formatters for each language.
Configuring format on save. The most important setting is Format On Save. Open VS Code Settings, search for Format On Save, and check the box. Now every time you press Ctrl + S, Prettier automatically reformats your entire file before saving. You never have to think about indentation again. You write messy code quickly, save the file, and Prettier cleans it instantly. This is the workflow professional developers use every day.
Setting Prettier as the default formatter. In VS Code Settings, search for Default Formatter and select esbenp.prettier-vscode from the dropdown. You can also configure this per language. For example, set Prettier as the default for JavaScript, HTML, CSS, and JSON individually if you prefer different formatters for other languages like Python.
Creating a Prettier configuration file. For team projects, you need a shared configuration so everyone formats code the same way. Create a file named .prettierrc in your project root. A typical configuration looks like this:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
This configuration enables semicolons, uses single quotes instead of double quotes, sets indentation to two spaces, and adds trailing commas where valid in ES5. When another developer opens your project and saves a file, their Prettier uses this configuration automatically. The code stays consistent regardless of who wrote it. Commit this file to your Git repository so the entire team shares the same rules.
Ignoring files. Create a .prettierignore file in your project root to exclude files that should not be formatted, such as minified libraries, build output folders, or generated files. This prevents Prettier from wasting time or breaking files that are not meant to be human-readable.
3. ESLint Basics
Prettier handles formatting. ESLint handles logic. It is a static analysis tool that reads your JavaScript code without executing it and flags potential errors, bugs, and violations of best practices. It catches unused variables, missing return statements, unreachable code, and dangerous patterns like using variables before they are declared. Think of Prettier as an editor that fixes your punctuation, and ESLint as a senior developer who reviews your code for mistakes before it runs.
Installing ESLint. In VS Code, open the Extensions panel and search for ESLint by Dirk Baeumer. Install it. For the command-line tool, open your terminal and run npm install eslint --save-dev inside your project folder. This installs ESLint as a development dependency, meaning it is required for working on the project but not for running it in production.
Initializing ESLint configuration. Run npx eslint --init in your terminal. This launches an interactive setup that asks about your environment, framework, and style preferences. It then generates an eslint.config.js or .eslintrc.json file containing your rules. For beginners, choose the recommended rule set, which enforces widely accepted best practices without being overly strict.
Basic rules you will encounter. no-unused-vars warns when you declare a variable but never use it, which often indicates a typo or incomplete logic. no-undef catches references to variables that do not exist. eqeqeq forces you to use strict equality === instead of loose equality ==, preventing type coercion bugs. no-console warns against leaving console.log statements in production code. Each rule can be set to off, warn, or error. Warnings let you build while reminding you. Errors prevent the build from succeeding until you fix the issue.
Integrating ESLint with Prettier. Prettier and ESLint can conflict because both want to control formatting. ESLint has formatting rules like indent and quotes that clash with Prettier's decisions. The solution is to install eslint-config-prettier, which disables all ESLint rules that conflict with Prettier. Then add "prettier" to the extends array in your ESLint configuration. Now Prettier handles formatting, and ESLint handles logic. They work together instead of fighting. In VS Code, enable Code: Actions On Save in settings and add "source.fixAll.eslint": "explicit" to automatically fix fixable ESLint errors every time you save.
Reading ESLint output. When ESLint finds an issue, it underlines the offending code in red or yellow in VS Code. Hover over the underline to see the rule name, a description of the problem, and often a suggested fix. Click the lightbulb icon that appears to apply the fix automatically. This immediate feedback loop, write code, see error, apply fix, is how you learn to write cleaner JavaScript without memorizing every rule.
4. Browser DevTools: Elements, Console, and Network Tab
Every modern browser ships with a suite of developer tools that let you inspect, debug, and profile your web pages in real time. You do not need to install anything. Press F12 or Ctrl + Shift + I in Chrome, Firefox, Edge, or Safari, and the DevTools panel opens. These three tabs, Elements, Console, and Network, are where you will spend 90 percent of your debugging time.
The Elements tab: inspecting and editing the DOM. The Elements tab shows the live HTML structure of your page, known as the Document Object Model. Click the arrow icon in the top-left corner of DevTools, then click any element on the page. The corresponding HTML is highlighted in the Elements panel. You can edit text directly in the panel by double-clicking it, and the page updates instantly. You can modify CSS properties in the Styles pane on the right, adding colors, margins, or fonts, and see the visual result immediately without reloading. These changes are temporary. Refreshing the page reverts them, which makes the Elements tab perfect for experimentation. Test twenty color combinations in seconds, find the one you like, then copy the final CSS into your actual file.
The Console tab: JavaScript execution and logging. The Console is a JavaScript playground. Type any valid JavaScript and press Enter to execute it in the context of the current page. You can query DOM elements with document.querySelector, inspect variables, or test functions. More importantly, the Console displays errors, warnings, and log messages from your code. If your script fails, the Console shows the exact file, line number, and error message. console.log() is the simplest debugging tool: insert it in your code to print variable values at specific points, then read the output in the Console. console.table() displays arrays and objects as sortable tables. console.error() and console.warn() print messages in red and yellow, making them easy to spot. Learn to read stack traces in the Console. A stack trace shows the sequence of function calls that led to an error, letting you trace backwards from the crash to the cause.
The Network tab: monitoring requests and responses. The Network tab records every HTTP request your page makes: HTML documents, CSS files, JavaScript files, images, API calls, fonts, and more. Open the Network tab before loading a page, then reload with Ctrl + R. You will see a waterfall chart showing every resource, when it started loading, how long it took, and whether it succeeded or failed. Click any request to inspect its headers, the data sent to the server, and the response received. This is essential for debugging API calls. If your frontend is not displaying data, the Network tab reveals whether the request failed, returned an error, or succeeded with empty data. The status code tells the story: 200 means success, 404 means the resource was not found, 500 means a server error, and 403 means forbidden. The Network tab also shows load times. If your page is slow, look for large images, unoptimized scripts, or requests that block each other. The Initiator column shows which file triggered each request, helping you trace unnecessary or redundant calls.
Preserving logs across reloads. By default, the Console clears when you reload the page. Check the Preserve log checkbox to keep messages across refreshes. In the Network tab, check Disable cache to ensure you are loading the latest versions of your files, not cached copies from previous visits. These two checkboxes prevent the most common debugging frustration: chasing a bug that was already fixed but hidden by cached code or cleared logs.
5. How Professional Teams Work with Git
Git is a version control system. It tracks every change you make to your code, lets you revert to previous versions, and enables multiple people to work on the same codebase without overwriting each other's work. But Git by itself is just a tool. The workflow, how branches are created, reviewed, merged, and deployed, is what determines whether a team ships smoothly or drowns in merge conflicts. This section covers the workflows that professional teams actually use in 2026.
The core principle: main must always be deployable. In every professional workflow, the main branch represents production-ready code. It should never contain broken features, failing tests, or incomplete work. Developers never push code directly to main. Instead, they create feature branches, isolated copies of the codebase where they experiment, build, and fix bugs without affecting anyone else.
Semantic branch naming. Professional teams use a directory-like naming convention that groups branches by type and owner. A typical structure is type/feature-name or owner/type/feature-name. Common prefixes include feat/ for new features, fix/ for bug fixes, docs/ for documentation updates, refactor/ for code restructuring without behavior changes, and chore/ for maintenance tasks like dependency updates. For example, feat/shopping-cart, jane/fix/payment-timeout, or docs/api-guide. The forward slash creates folders in Git interfaces, making it easy to navigate dozens of branches. This naming convention also helps automation tools and CI/CD pipelines trigger different actions based on branch type.
GitHub Flow: the standard for small teams and web apps. GitHub Flow is the simplest professional workflow. Create a feature branch from main, write your code, open a pull request, request review from teammates, address feedback, and merge back to main. Then deploy. There is no develop branch, no release branch, and no hotfix branch. The simplicity works because the team is small, the product is a web application, and there is only one production version live at any time. Every merge to main triggers an automatic deployment if the tests pass. The critical requirement is that main must truly be always deployable, which means every pull request must pass automated tests and code review before merging.
Pull requests and code review. A pull request is a formal request to merge your branch into main. It is the primary mechanism for code review. When you open a pull request, you describe what you changed and why. Teammates read the diff, a line-by-line comparison showing exactly what was added, removed, or modified. They leave comments, ask questions, and request changes. Only after approval does the merge happen. In 2026, many teams use AI-assisted review tools that scan for security vulnerabilities, logic errors, and coding standard violations before human reviewers see the code. This does not replace human review. It accelerates it by catching obvious issues first, allowing humans to focus on architecture, maintainability, and whether the code actually solves the business problem.
Squash and merge for clean history. When developing a feature, developers often make dozens of small commits: fix typo, adjust padding, try again, finally works. These intermediate commits are useful while working but clutter the project history if preserved. Squash and merge collapses all commits in a pull request into a single meaningful commit before merging. The main branch history becomes a clean sequence of complete features, not a mess of half-finished experiments. This makes rollback easier, changelog generation automatic, and history readable. On GitHub, click the dropdown arrow next to the Merge button and select Squash and merge. Write a clear final commit message following semantic conventions like feat: add user authentication or fix: resolve checkout timeout.
The four-tier environment pipeline. Enterprise teams deploy code through multiple environments before it reaches users. Develop is the integration branch where all feature branches merge. It is used to verify that features work together. QA is where testers perform rigorous testing, stress testing, and automation testing. UAT, User Acceptance Testing, is where clients or end users verify that the system meets business requirements. Production is the live environment. Code moves through these gates sequentially. No one pushes directly to production. Promotion happens through pull requests or automated pipelines, with approval required at each stage. This separation prevents bugs from reaching users and provides rollback points if something breaks.
Trunk-based development for high-velocity teams. Trunk-based development is an advanced workflow where developers commit directly to main or use extremely short-lived branches, measured in hours rather than days. Incomplete features are hidden behind feature flags, toggles that enable or disable functionality without deploying new code. This workflow requires strong automated testing, fast CI pipelines, and a team culture where breaking main is treated as an emergency. It is common at high-growth product companies that deploy multiple times per day. For bootcamp projects and small teams, GitHub Flow is the appropriate starting point. Understand trunk-based development as the destination, but master the basics first.
Quick recap: Emmet expands abbreviations into full HTML and CSS with Tab, using operators like > for nesting, * for multiplication, $ for numbering, and # and . for IDs and classes · Prettier formats code automatically on save, configured via .prettierrc for team consistency · ESLint catches logic errors and enforces best practices, integrated with Prettier via eslint-config-prettier to avoid conflicts · Browser DevTools let you inspect the DOM in Elements, execute JavaScript and read logs in Console, and monitor HTTP requests in Network · Professional Git workflows use feature branches with semantic names, pull requests for review, squash and merge for clean history, and multi-tier environments for safe deployment.
Using AI to Move Faster in Development Workflows
The tools in this lesson are already automation. They remove repetitive work so you can focus on solving problems. AI adds another layer of acceleration on top of these tools, helping you write code faster, debug smarter, and collaborate more effectively. Here is how to integrate AI into this workflow without letting it replace your understanding.
1. Use AI to generate Emmet abbreviations for complex structures.
If you need a deeply nested component, for example a card grid with headers, images, descriptions, and buttons, describe it to an AI assistant: "Write an Emmet abbreviation for a section containing three article cards, each with an image, an h3 title, a paragraph, and a button with the class btn-primary." AI will produce something like section>article*3>img+h3+p+button.btn-primary. Copy it, press Tab in VS Code, and your structure appears instantly. This is faster than constructing the abbreviation manually, especially when you are still learning the syntax.
2. Let AI configure Prettier and ESLint for your project.
Setting up Prettier and ESLint with the correct integration can be confusing the first time. Describe your project to AI: "I am building a React project with TypeScript. Generate a complete Prettier config and ESLint config that work together without conflicts, and list the VS Code settings I need." AI will generate the .prettierrc, eslint.config.js, and the VS Code settings.json entries. Review each rule to ensure it matches your team's preferences, then commit the files. This saves an hour of reading documentation and troubleshooting conflicts.
3. Debug faster with AI interpreting Console and Network errors.
When the Console shows a cryptic error like TypeError: Cannot read properties of undefined (reading 'map'), paste the error and the surrounding code into an AI assistant and ask: "What causes this error and how do I fix it?" AI will explain that you are calling .map on a variable that is undefined or not an array, and suggest adding a conditional check or ensuring the data is fetched before rendering. Similarly, if a Network tab request returns a 404 or 500, paste the request URL, headers, and response into AI and ask for diagnosis. AI can spot missing authentication tokens, incorrect endpoint paths, or malformed request bodies faster than manual inspection.
4. Generate Git commit messages and pull request descriptions.
Writing clear commit messages is a discipline that takes time to develop. After staging your changes with git add, use an AI tool that reads your diff and suggests a semantic commit message like feat: add responsive navigation bar with mobile hamburger menu. For pull requests, AI can summarize your changes, list the files modified, and draft a description explaining what was changed and why. You should always edit the draft to add context that AI cannot know, such as the business requirement that motivated the change. But the draft gives you a professional structure to start from, preventing the vague one-line pull requests that frustrate reviewers.
5. Use AI to review your code before human review.
Before opening a pull request, paste your code into an AI assistant and ask: "Review this code for potential bugs, performance issues, and adherence to modern JavaScript best practices." AI will flag unused variables, suggest more efficient array methods, warn about potential null reference errors, and recommend clearer variable names. Fix the issues AI finds before submitting to your teammates. This reduces the number of review cycles, shows respect for your reviewers' time, and trains you to write cleaner code naturally. Remember that AI is a first line of defense, not a replacement for human review. It catches syntax and pattern errors. Humans catch logic, architecture, and business requirement errors.
A habit worth building from this lesson onward: before starting any coding session, ensure your tools are configured. Prettier should format on save. ESLint should underline errors in real time. Emmet should be active. Git should track your changes. Then, when you encounter a problem, use AI to accelerate the solution, but never skip the step of understanding why the solution works. Tools make you fast. Understanding makes you valuable.
Next lesson: HTML structure, semantic elements, and accessibility fundamentals.