Skip to main content

JavaScript — NHS Quickstart

🟨 Node.js scripting · SQL Server access · Express/Next.js · Front‑end UIs
Why JavaScript/Node matters in the NHS

JavaScript runs everywhere. With Node you can script ETL tasks, expose secure APIs (Express/Fastify), or build UIs (React/Next.js). One language lets you go from database → service → front‑end fast.

Common NHS uses

  • Lightweight REST APIs that sit in front of SQL Server views.
  • Small ETL/automation tasks with cron/schedulers.
  • UI prototypes for clinicians/ops teams (React/Next.js).
  • Calling internal/external APIs (NHS Digital, FHIR endpoints, Open Data).

⚙️ 10‑minute install

# 1) Install Node.js LTS from https://nodejs.org (includes npm)
node -v
npm -v

# Optional: nodemon for auto-reload during dev
npm i -g nodemon

🚀 “Hello NHS” (Node script)

Create hello_nhs.mjs:

hello_nhs.mjs
const admissions = [
{ date: '2025-01-01', patients: 120 },
{ date: '2025-01-02', patients: 135 },
{ date: '2025-01-03', patients: 128 },
];

const total = admissions.reduce((s, r) => s + r.patients, 0);
const avg = (total / admissions.length).toFixed(1);

console.log('Admissions summary for 3 days:');
console.log({ total, average: Number(avg) });

Run:

node hello_nhs.mjs

🔗 Connect to SQL Server (safe pattern)

Install deps:

npm i mssql dotenv

Create .env (do not commit):

.env
SQLSERVER_SERVER=YOURSERVER
SQLSERVER_DATABASE=NHS_Analytics
SQLSERVER_USER=readonly_user # (Prefer read-only)
SQLSERVER_PASSWORD=************ # Avoid for cloud; use Key Vault/Secrets Manager

Create query_sqlserver.mjs:

query_sqlserver.mjs
import 'dotenv/config';
import sql from 'mssql';

const config = {
server: process.env.SQLSERVER_SERVER,
database: process.env.SQLSERVER_DATABASE,
user: process.env.SQLSERVER_USER,
password: process.env.SQLSERVER_PASSWORD,
options: {
encrypt: true, // TLS
trustServerCertificate: false,
},
pool: { max: 5, min: 0, idleTimeoutMillis: 30000 },
};

const pool = new sql.ConnectionPool(config);

try {
await pool.connect();
const result = await pool
.request()
.query(`
SELECT TOP (50)
practice_id, total_appointments, attendance_rate, median_wait_minutes
FROM dbo.vw_PracticeKPI
ORDER BY total_appointments DESC
`);
console.log(result.recordset.slice(0, 5));
} finally {
pool.close();
}

Run:

node query_sqlserver.mjs

Windows Integrated Auth? Use the msnodesqlv8 driver with mssql on domain‑joined machines, or prefer Managed Identity when deploying to Azure. Keep SQL passwords out of code; use a secret store in prod.


🧪 Optional: tiny Express API (≈15 min)

npm i express mssql dotenv

Create server.mjs:

server.mjs
import 'dotenv/config';
import express from 'express';
import sql from 'mssql';

const app = express();
const pool = new sql.ConnectionPool({
server: process.env.SQLSERVER_SERVER,
database: process.env.SQLSERVER_DATABASE,
user: process.env.SQLSERVER_USER,
password: process.env.SQLSERVER_PASSWORD,
options: { encrypt: true, trustServerCertificate: false },
});

app.get('/kpi', async (_req, res) => {
try {
await pool.connect();
const r = await pool.request().query(`
SELECT TOP (20) practice_id, total_appointments, attendance_rate, median_wait_minutes
FROM dbo.vw_PracticeKPI
ORDER BY total_appointments DESC
`);
res.json(r.recordset);
} catch (err) {
console.error(err);
res.status(500).json({ error: 'query_failed' });
} finally {
pool.close();
}
});

app.listen(8000, () => console.log('API http://localhost:8000/kpi'));

Run:

node server.mjs
# or: nodemon server.mjs

Now any front‑end (React/Vite, Next.js) can fetch('http://localhost:8000/kpi') and render a table/chart.


🧰 NHS‑ready packages

PackageUse case
mssqlSQL Server access (TLS on by default)
dotenvload secrets from .env (local only)
expresssimple REST APIs
node-fetch / axioscall external/internal APIs
zodvalidate request/response shapes
winston / pinostructured logging
node-cronscheduled jobs
csv-parseCSV ingestion for open datasets

🖥 IDE setup (VS Code)

  1. Install VS Code.
  2. Add extensions: ESLint, Prettier, GitHub Pull Requests & Issues, DotENV.
  3. Create a minimal ESLint/Prettier setup for consistent code style.
.eslintrc.json
{
"env": { "es2022": true, "node": true },
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
"rules": { "no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }] }
}

🔒 IG & safety checklist

  • Use synthetic/de‑identified datasets in examples.
  • Keep secrets out of code; use .env locally and Key Vault/Secrets Manager in prod.
  • Enforce TLS (options.encrypt=true) and prefer read‑only SQL users.
  • Avoid logging PHI; use structured logs with redaction.
  • Document source tables, owners, and refresh cadence in your repo.

📏 Measuring impact

  • Velocity: time from “new folder” → API responding with JSON.
  • Reliability: uptime of the API; % successful scheduled jobs.
  • Quality: lint passes, unit tests, PR reviews.
  • Reusability: can a teammate clone and run with only a .env?

🔗 See also

What’s next?

You’ve completed the Learn — JavaScript stage. Keep momentum: