gl.createBuffer and gl.bufferData create buffers for WebGL. Whether those are on the GPU or not is up to the platform and browser. AFAIK All Intel GPUs store vertex data in the same memory as other CPU data. Also some WebGL implementations might store copies of buffers in CPU ram as well so there's really no way to know.
gl.bufferData sets the size of a buffer and puts data in it.
// create buffer
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
// set it's size to size of data and copy data into it
const data = new Uint8Array([1, 2, 3, 4, 5]);
gl.bufferData(g.ARRAY_BUFFER, data, gl.STATIC_DATA);
You don't want to put data in it pass in a size instead of an TypedArray
// create buffer
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
// set it's size to 1024 bytes
gl.bufferData(g.ARRAY_BUFFER, 1024, gl.STATIC_DATA);
After that you can put data in it a little at a time with gl.bufferSubData. Example
const offset = 100;
gl.bufferSubData(gl.ARRAY_BUFFER, offset, someTypedArray);
someTypedArray is just that, a TypedArray like
const someTypedArray = new Uint8Array(45);
In which case the buffer would have bytes 100 to 144 get updated with the contents of someTypedArray
Or if you want to use a part of an TypedArray then you can make view
const someTypedArray = new Uint8Array(1024);
...
const bufferOffset = 200;
cconstonst bufferLength = 50;
var someOtherTypedArray = new Uint8Array(
someTypedArray.buffer,
someTypedArray.byteOffset + bufferOffset,
bufferLength);
That makes someOtherTypedArray a view into someTypedArray that starts 200 bytes into someTypedArray and is 50 bytes long.