JSFiddle - React, Tailwind, and code Playground

HTML

<script type="importmap">
	{
		"imports": {
			"three": "https://unpkg.com/three@0.170.0/build/three.module.js",
      "three/addons/": "https://unpkg.com/three@0.170.0/examples/jsm/"
		}
	}
</script>

CSS

body {
	  margin: 0;
    overflow: hidden;
}

JavaScript

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const width = window.innerWidth, height = window.innerHeight;

// init

const camera = new THREE.PerspectiveCamera( 70, width / height, 0.01, 100 );
camera.position.z = 1.5;

const scene = new THREE.Scene();

const geometry = extrudeDisc();
const material = new THREE.MeshNormalMaterial();

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

const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
renderer.setAnimationLoop( animate );
document.body.appendChild( renderer.domElement );

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

// animation

function animate( time ) {

	renderer.render( scene, camera );

}

window.onresize = () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}

function extrudeDisc(
    innerRadius = 0.4,
    outerRadius = 0.6,
    depth = 0.1,
    bevelSize = 0.05,
    bevelThickness = 0.05,
    bevelOffset = 0,
    bevelSegments = 12,
    curveSegments = 128
  ) {
   
    const shape = new THREE.Shape();
    shape.moveTo(outerRadius, 0);
    shape.absarc(0, 0, outerRadius, 0, Math.PI * 2, false);
    shape.closePath()

    const holePath = new THREE.Path();
    
    holePath.absarc(0, 0, innerRadius, 0, Math.PI * 2, true);
    holePath.closePath(); 
    shape.holes.push(holePath);

    return new THREE.ExtrudeGeometry(shape, {
      depth,
      bevelEnabled: true,
      bevelSize,
      bevelThickness,
      bevelOffset, 
      bevelSegments,
      curveSegments,
    });
  }