Minimal, very simple, implementation of an HTTP server for static content, using only core node.js modules To practice the very basics of node back-end, I'm implementing the most basic server possible for static content, using only the core node modules:

http
fs
path

With the following server requirements:

Can serve any http file inside the public directory.
Accepts only GET requests, 404 for anything else.
Accepts only .html extensions, 404 for anything else.
Use public/not-found.html for 404s.

These requirements are arbitrary, just to include some very basic logic in the request and response handling.
The working solution I'm presenting for code review is the following:
const fs = require('fs')
const http = require('http')
const path = require('path')

const hostname = 'localhost'
const port = 3000
const runLog = `Server running ar http://${hostname}:${port}`
const rootPath = '../public'
const errorPath = `${rootPath}/not-found.html`

const server = http.createServer((req, res) =&gt; {
  const fileUrl = req.url === '/' ? '/index.html' : req.url
  const filePath = path.resolve(`${rootPath}${fileUrl}`)
  res.setHeader('Content-Type', 'text/html')

  if (reqIsOk(req, filePath)) {
    res.statusCode = 200
    fs.createReadStream(filePath).pipe(res)
  } else {
    res.statusCode = 404
    fs.createReadStream(errorPath).pipe(res)
  }
})

function reqIsOk (req, filePath) {
  const fileExt = path.extname(filePath)
  return req.method === 'GET' &amp;&amp; fileExt === '.html' &amp;&amp; fs.existsSync(filePath)
}

server.listen(port, hostname, () =&gt; {
  console.log(runLog)
})

I'm looking for all kind of feedback, from style, code smells, anti-patterns, anything that can be improved is very welcome.

Are the fs and path packages needed? Do they simplify things enough to justify the inclusion?
Can this be written more concisely?
Is the ternary operator justified? Would you keep it here, or is an if construct preferred?
Are the fs and path packages needed? Do they simplify things enough to justify the inclusion?

fs is needed. How else would you get your data down the line without reading it in? path could be replaced with your own path utility library, but I wouldn't waste time reinventing that when a built-in one already exists.

Can this be written more concisely?

This is probably as concise as you can get it. Any further would probably make it unreadable.

Is the ternary operator justified? Would you keep it here, or is an if construct preferred?

Yep, ternary is fine. It's the check that might need improvement. That's because you're only tacking on index.html if the path is /. In other web servers, any path that ends in / assumes that index.html will be tacked on.
const filePath = path.resolve(`${rootPath}${fileUrl}`)

So one of the dangers when writing a web server is directory traversal. It's when your path resolver (in your case, this line) resolves to a path outside the web directory, and your server just willingly serves it. You'll need to check if the path resolved is still in your web directory.
res.setHeader('Content-Type', 'text/html')

function reqIsOk (req, filePath) {
  const fileExt = path.extname(filePath)
  return req.method === 'GET' &amp;&amp; fileExt === '.html' &amp;&amp; fs.existsSync(filePath)
}

A static server can be more than just HTML. Replace the hardcoded text/html with a value coming from a map of file extension to mimetype.