Which JavaScript Code Can Be Written? A Practical Guide

Explore what JavaScript code you can write across runtimes—from browsers to Node.js—and learn practical patterns, modules, DOM interactions, and tooling with concrete examples for developers.

JavaScripting
JavaScripting Team
·5 min read
JavaScript Code Guide - JavaScripting
Photo by ricardorv30via Pixabay
Quick AnswerDefinition

JavaScript code runs in multiple runtimes (browsers, Node.js, and beyond). You can write functions, classes, modules, async/await flows, and even DOM interactions in the browser. The exact syntax and tooling depend on the environment, so this guide clarifies what you can write and how to structure it effectively for teams building scalable apps, and for learners who want to experiment safely.

What kinds of JavaScript code can be written?

JavaScript code exists across runtimes and use cases. In modern projects you’ll write a mix of functional helpers, classes, modular code, and asynchronous flows. According to JavaScripting, the landscape is expansive, but conventions help keep large codebases maintainable. The patterns shown here reflect typical browser, Node.js, and tooling environments. The ability to write these patterns depends on runtime and module system; understand your target environment to pick the right syntax and structure for your codebase. for teams building scalable apps, and for learners who want to experiment safely.

JavaScript
function greet(name) { return `Hello, ${name}!`; }
JavaScript
const add = (a, b) => a + b;
JavaScript
class Counter { constructor(){ this.n = 0 } increment(){ this.n++ } }

Notes:

  • Functions and classes run in both browsers and Node.js, but module imports/exports may differ.
  • Use ES modules where possible to enable clean imports and tree-shaking.

Where code runs: Browsers, Node.js, and beyond

JavaScript code executes in a variety of environments. In browsers you have access to the DOM and browser APIs, while in Node.js you manipulate the file system and serverside resources. Cross-environment code often relies on feature detection and polyfills. The following snippets illustrate environment checks and how to keep code portable across runtimes.

JS
if (typeof window !== 'undefined') { console.log('Browser environment'); } else if (typeof globalThis !== 'undefined') { console.log('Node.js or other runtime'); }
JS
// Browser-specific: DOM access if (typeof document !== 'undefined') { document.title = 'JS in the Browser'; } // Node-specific: file system if (typeof require !== 'undefined') { const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (!err) console.log(data); }); }

Core language features you can write

JavaScript provides a rich set of constructs you’ll use daily. Here are representative patterns that work in both browsers and Node.js (with appropriate runtime support).

JavaScript
// Function declaration function double(n) { return n * 2; }
JavaScript
// Array manipulation with higher-order functions const nums = [1, 2, 3]; const doubled = nums.map(n => n * 2);
JavaScript
// Async function with Promise handling async function fetchJson(url) { const res = await fetch(url); return res.json(); }

Why it matters: Functions, arrays, objects, and async flows form the backbone of any non-trivial codebase. Use meaningful names, keep functions small, and document intent for easier maintenance.

Modules, packaging and bundling

Module systems enable scalable code organization. ES modules (import/export) are now the standard in modern JS, while CommonJS remains prevalent in older Node.js projects. The examples show typical module usage and how bundlers resolve dependencies for browser deployments.

JavaScript
// geometry.js (ES module) export const pi = 3.14159; export function area(r) { return pi * r * r; }
JavaScript
// app.js (ES module consumer) import { area } from './geometry.js'; console.log(area(5));
JavaScript
// CommonJS variant (older Node.js) exports.area = function area(r) { return r * r; };

Tip: Prefer ES modules in new projects and use a bundler for browser targets. In Node, you can opt into ES modules by using the .mjs extension or setting "type": "module" in package.json.

Asynchronous patterns and data flows

Asynchronous code is central to modern JavaScript, from network requests to file I/O. You’ll typically use Promises, async/await, and concurrency helpers to keep code non-blocking and readable.

JavaScript
// Delay wrapper using Promise function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } delay(500).then(() => console.log('done'));
JavaScript
// Async/await example with fetch async function getData(url) { const res = await fetch(url); const data = await res.json(); return data; }
JavaScript
// Concurrent operations with Promise.all Promise.all([fetch('/a'), fetch('/b')]) .then(([r1, r2]) => Promise.all([r1.json(), r2.json()])) .then(([d1, d2]) => console.log(d1, d2));

Best practice: keep async functions small, handle errors explicitly with try/catch, and avoid mixing sync and async code in the same function. This improves traceability during debugging and testing.

DOM manipulation and browser APIs

Browser APIs let you create dynamic user interfaces. This block demonstrates common patterns for updating the DOM and handling events, which are central to client-side JavaScript.

JavaScript
// Update the content of a DOM node document.getElementById('status').textContent = 'Ready';
JavaScript
// Attach an event listener document.querySelector('#submit').addEventListener('click', () => { console.log('Submitted'); });
JavaScript
// Simple animation loop (requestAnimationFrame) let t = 0; function loop() { t += 16; // update visuals here using t requestAnimationFrame(loop); } requestAnimationFrame(loop);

Note: DOM APIs are browser-specific. For universal code, guard DOM interactions with runtime checks or load them behind feature flags to avoid errors in non-browser environments.

Testing, tooling, and deployment readiness

A robust JavaScript project uses tooling to maintain quality and speed up iteration. This block highlights essential commands and workflows for testing, linting, and transpiling.

Bash
# Linting npx eslint .
Bash
# TypeScript setup (optional but common) tsc --init
Bash
# Transpiling with Babel for broader compatibility npx babel src --out-dir dist

Tip: Integrate tests and linting into your CI pipeline to catch regressions early and enforce coding standards across the team.

Steps

Estimated time: 60-90 minutes

  1. 1

    Set up your workspace

    Install Node.js, create a project directory, and initialize npm. This creates a baseline to install tooling and dependencies needed for writing JS in multiple runtimes.

    Tip: Use a consistent project structure from the start to simplify imports.
  2. 2

    Create source files

    Add a few source files (e.g., hello.js, constants.js) to illustrate modules and exports. Keep files focused and named clearly.

    Tip: Name modules by their responsibility to ease discovery.
  3. 3

    Add module exports and imports

    Export functions from one module and import them in another. This demonstrates clean separation of concerns and tree-shaking benefits.

    Tip: Prefer named exports over default exports for clarity.
  4. 4

    Run code in different runtimes

    Execute scripts via Node for server-side logic and load modules in a basic HTML page for browser testing. Validate behavior in both environments.

    Tip: Guard browser-specific APIs behind feature checks when sharing code.
  5. 5

    Introduce async flows

    Add a small async function that fetches data and processes it. Use await for readability and error handling patterns.

    Tip: Always handle errors with try/catch in async functions.
  6. 6

    Lint, test, and iterate

    Run ESLint and unit tests frequently during development. Integrate into CI for consistent quality across the team.

    Tip: Automate checks to prevent drift in larger codebases.
Pro Tip: Prefer ES modules for modern codebases to enable tree-shaking and clean imports.
Warning: Avoid DOM access in non-browser environments; guard with runtime checks.
Note: Write small, testable units; compose them to form larger features.
Pro Tip: Use async/await for readability; keep error handling explicit.

Prerequisites

Required

Commands

ActionCommand
Create a new project directorySets up a workspace for code and toolingmkdir my-js-project && cd my-js-project
Initialize npm projectCreates package.json with defaultsnpm init -y
Install Babel for ES module transpilingPrepares environment for transpiling to broader runtimesnpm install --save-dev @babel/core @babel/preset-env
Run a JS file with NodeExecutes a script in the Node runtimenode index.js
Transpile with BabelConverts modern JS so older environments can run itnpx babel src --out-dir dist
Run ESLintChecks code quality and enforces rulesnpx eslint .

Questions & Answers

Can I run JavaScript in a browser without a server?

Yes. You can run JavaScript directly in the browser by embedding scripts in HTML or loading modules via a <script type="module"> tag. This enables DOM access and client-side interactions without a server. For broader distribution, you may serve static files via a lightweight server during development.

Yes — you can run JS directly in the browser by loading scripts in HTML. No server is required for client-side code, though you might use a simple server for testing production-like scenarios.

What is ES modules and why use them?

ES modules provide a standard syntax for importing and exporting bindings between files. They improve readability, support static analysis, and enable tree-shaking in bundlers. Use import/export in modern projects for scalable, maintainable code.

ES modules let you import and export pieces of code between files. They help keep code organized and optimize builds.

What’s the difference between CommonJS and ES modules?

CommonJS is older and uses require/module.exports, mainly in Node.js. ES modules use import/export syntax and work in both browsers (with transpilation) and Node.js (with proper configuration). ES modules enable static analysis and better optimization in modern tooling.

CommonJS uses require; ES modules use import and export. ES modules are the modern standard and work across browsers and Node with the right setup.

Is TypeScript allowed in this workflow?

TypeScript is a superset of JavaScript that adds static typing. You can integrate it by configuring a TS compiler or a build step in your pipeline, then compile to JavaScript for runtime execution.

Yes, you can use TypeScript by adding a compile step; it compiles to JavaScript for runtime.

How do you debug JavaScript code effectively?

Use browser devtools for client-side code and Node.js inspectors or IDE debuggers for server-side code. Set breakpoints, inspect variables, and use console logging judiciously to understand behavior.

Debug with the built-in tools in your browser or Node debugger; set breakpoints and inspect state step by step.

What to Remember

  • Understand where JavaScript code runs (browser vs Node).
  • Use modules to structure code and enable reuse.
  • Adopt async/await patterns for non-blocking operations.
  • Test and lint early to maintain quality across runtimes.

Related Articles