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
- Windows (recommended)
- macOS / Linux
# 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
# 1) Install Node.js LTS (brew, apt, asdf, or nvm)
node -v
npm -v
# Optional: nodemon for auto-reload
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
msnodesqlv8driver withmssqlon 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
| Package | Use case |
|---|---|
mssql | SQL Server access (TLS on by default) |
dotenv | load secrets from .env (local only) |
express | simple REST APIs |
node-fetch / axios | call external/internal APIs |
zod | validate request/response shapes |
winston / pino | structured logging |
node-cron | scheduled jobs |
csv-parse | CSV ingestion for open datasets |
🖥 IDE setup (VS Code)
- Install VS Code.
- Add extensions: ESLint, Prettier, GitHub Pull Requests & Issues, DotENV.
- 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
.envlocally 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: