The solution is to make a larger canvas, say, 800x800 and put it into that 400x400 space.
Here is an example, using that MDN code, with a 400x400 canvas (red) next to a 800x800 canvas (blue). CSS is forcing them both to appear the same 400x400 size. The blue one should look sharper on most devices.
Note how the 800x800 canvas needs to be scaled double with ctx2.scale(2,2) so that it appears correct.
https://codepen.io/simonsarris/pen/eYexbOb
Pixel ratio is variable (window.devicePixelRatio), so this canvas pixel density is something you'll want to programmatically set for each user.