Serving a webpage that displays the HTTP request information sent by the client In order to learn web server programming in Node and JavaScript, I decided to implement a simple web server that only does one thing:

Display data of the HTTP request as an HTML table.

The actual data to display is arbitrary. In this example I'm displaying the contents of the header, along with the method, url, and http versions.
Here is the working solution:
const http = require('http');

const port = 3344;

const htmlCSS = `
  &lt;style&gt;
    body {
      font-family: sans-serif;
    }

    td {
      border: 1px solid black;
      padding: 0.5rem;
    }

    table {
      margin: 0 auto;
    }
  &lt;/style&gt;
`;

const server = http.createServer((req, res) =&gt; {
  const {
    headers,
    method,
    url
  } = req;

  console.log(`\n${headers['user-agent']}\n${method}\n${url}`);
  console.log(new Date());
  console.log();

  writeResponse(req, res);
});

server.listen(port);

function writeResponse(req, res) {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');
  writeBody(req, res);
  res.end();
}

function writeBody(req, res) {
  const htmlTitle = '&lt;title&gt;Your Request Is&lt;/title&gt;';
  const htmlEncode = '&lt;meta charset=&quot;UTF-8&quot;&gt;';
  const htmlHead = `&lt;head&gt;${htmlTitle}${htmlCSS}${htmlEncode}&lt;/head&gt;`;
  const htmlTop = `&lt;html lang=&quot;en&quot;&gt;${htmlHead}&lt;body&gt;`;
  const htmlBot = '&lt;/body&gt;&lt;/html&gt;';

  res.write(htmlTop);
  writeTable(req, res);
  res.write(htmlBot);
}

function writeTable(req, res) {
  const htmlTableTop = '&lt;table&gt;&lt;tbody&gt;';
  const htmlTableBot = '&lt;/tbody&gt;&lt;/table&gt;';

  res.write(htmlTableTop);
  writeAllRows(req, res);
  res.write(htmlTableBot);
}

function writeAllRows(req, res) {
    const {
    httpVersion,
    httpVersionMinor,
    httpVersionMajor,
    headers,
    method,
    url
  } = req;

  for (const key in headers) {
    writeRow(res, key, headers[key]);
  }
  writeRow(res, 'method', method);
  writeRow(res, 'url', url);
  writeRow(res, 'httpVersion', httpVersion);
  writeRow(res, 'httpVersionMinor', httpVersionMinor);
  writeRow(res, 'httpVersionMajor', httpVersionMajor);
}

function writeRow(res, key, val) {
  const entry = `&lt;tr&gt;&lt;td&gt;${key}&lt;/td&gt;&lt;td&gt;${val}&lt;/td&gt;&lt;/tr&gt;`;
  res.write(entry);
}

While I have some particular questions, I'm looking forward for all kinds of feedback! So if you see anything at all that can be improved, any comment is much appreciated!

Can I use other modules to make this job easier?
For a job this simple, is it worth to work with HTML and CSS as separate files?
How are HTML and CSS normally handled inside JS files (edits, appends, etc)?
How well am I handling the construction of HTML and CSS?
Can this be done more concisely?
What would you do differently to improve this in any way?
Can I use other modules to make this job easier?

You can use some web framework like fastify or express.
This would ease the code a lot

For a job this simple, is it worth to work with HTML and CSS as separate files?

Assumig your project will grown, it is a good approach to move some &quot;static text&quot; in a separated file.

How are HTML and CSS normally handled inside JS files (edits, appends, etc)?

You have made a server side rendering (SSR) by your hand.
Since it would be hard to manage manually all those piece of strings and would be also dandgerous to
some script injection, you could use some fremework as vue
or other templating systems like handlebarsjs or others - here a list

How well am I handling the construction of HTML and CSS?

There could be some security issue for links like that if you start to process those values:
http://localhost:3000/?user=%3Cimg%20src=%27aaa%27%20onerror=alert(1)%3E
the framework protect you from these cases usually.
This code:
  const htmlTitle = '&lt;title&gt;Your Request Is&lt;/title&gt;'
  const htmlEncode = '&lt;meta charset=&quot;UTF-8&quot;&gt;'
  const htmlHead = `&lt;head&gt;${htmlTitle}${htmlCSS}${htmlEncode}&lt;/head&gt;`
  const htmlTop = `&lt;html lang=&quot;en&quot;&gt;${htmlHead}&lt;body&gt;`

produce every time the same output string, so you could do it once instead of every request:
this will stress less the nodejs garbage collector for high throughput site.

Can this be done more concisely?

You could write less code using some Object and Array functions:
function stringTemplates (request) {
  return `&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;title&gt;Your Request Is&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table&gt;&lt;tbody&gt;
${Object.entries(request.headers).map(processLine).join('')}
${['httpVersion', 'httpVersionMinor', 'httpVersionMajor', 'method', 'url'].map(prop =&gt; processLine([prop, request[prop]])).join('')}
&lt;/tbody&gt;&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
`
}

function processLine ([header, value]) {
  return `&lt;tr&gt;&lt;td&gt;${header}&lt;/td&gt;&lt;td&gt;${value}&lt;/td&gt;&lt;/tr&gt;`
}


What would you do differently to improve this in any way?

This shows only GET, but in order to learn the HTTP standard it would useful to show in:

query parameters
form parameter (with different encoding)