JSFiddle - React, Tailwind, and code Playground

CSS

body {
  margin: 0;
}

canvas {
  display: block;
	outline: none;
}

JavaScript

import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.121.1/build/three.module.js';
import {
  OrbitControls
} from 'https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js';

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
  camera.position.z = 50;

  scene = new THREE.Scene();

  const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.4);
  hemiLight.position.set(0, 50, 0);
  scene.add(hemiLight);

  const dirLight = new THREE.DirectionalLight(0xffffff, 0.6);
  dirLight.position.set(-30, 50, 50);
  scene.add(dirLight);

  const radius = 25;

  const path = new THREE.Curve();
  path.getPoint = (t) => {
    const radians = 2 * Math.PI * t;
    return new THREE.Vector3(radius * Math.cos(radians),
      radius * Math.sin(radians),
      0);
  };

  const shape = new THREE.Shape();
  shape.ellipse(0, 0, 5, 3, 0, 0, true, 0);

  const extrudeSettings = {
    depth: 10,
    steps: 100,
    bevelEnabled: false,
		extrudePath: path
  };

  const geometry = new THREE.ExtrudeBufferGeometry(shape, extrudeSettings);
  geometry.center();
  geometry.computeVertexNormals();
    
  const material = new THREE.MeshPhongMaterial();

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const controls = new OrbitControls(camera, renderer.domElement)

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}