JSFiddle - React, Tailwind, and code Playground

HTML

<body>
		<div id="encoder_container">		
			<textarea autofocus id="encoder_text_input" class="text"></textarea>
			<textarea readonly id="encoder_text_output" class="text"></textarea>
		</div>
		<div id="decoder_container">
			<textarea autofocus id="decoder_text_input" class="text"></textarea>
			<textarea readonly id="decoder_text_output" class="text"></textarea>	
		</div>
		<script src="code.js"></script>
	</body>

CSS

.text {
	width: 400px;
	height: 200px;
	resize: none;
}
#encoder_container {
	text-align: center;
	background-color: lightgreen;
}
#decoder_container {
	text-align: center;
	background-color: lightblue;
}

JavaScript

var last_codepoint = 0xFE00;
var debug = "";
document.
	getElementById("encoder_text_input").
	addEventListener(
		"input",
		function(e){
			debug = "";
			var result = "";
			for(var v of e.target.value) {
				result += encode_codepoint(v.codePointAt(0));
			}
			document.getElementById("encoder_text_output").value = result;// + "\nBELOW ARE DEBUG INFORMATIONS. PLEASE IGNORE. THANK YOU.\n" + debug;
      /*
			document.getElementById("decoder_text_input").value = result;
			var event = new MouseEvent("input", {
			    'view': window,
			    'bubbles': true,
			    'cancelable': true
			  });
			document.getElementById("decoder_text_input").dispatchEvent(event);
      */
		}
	);
document.
	getElementById("decoder_text_input").
	addEventListener(
		"input",
		function(e){
			document.getElementById("decoder_text_output").value = decode_string(e.target.value);
		}
	);
function decode_string(encoded_string) {
	var result = "";
	var replacements = [String.fromCodePoint(0xFEFF), String.fromCodePoint(0x180E), String.fromCodePoint(last_codepoint)];//2d7f
	var cleaning_regex = new RegExp("[^"+replacements[0]+replacements[1]+replacements[2]+"]{1}", "g");
	encoded_string = encoded_string.replace(cleaning_regex, "");
	var replacements_regexes = [
		new RegExp(replacements[0], "g"),
		new RegExp(replacements[1], "g"),
		new RegExp(replacements[2], "g")
	];
	encoded_string = encoded_string.replace(replacements_regexes[0], "0");
	encoded_string = encoded_string.replace(replacements_regexes[1], "1");
	encoded_string = encoded_string.replace(replacements_regexes[2], "2");
	while(encoded_string.length) {
		var decoded_data = decode_codepoint(encoded_string);
		result += decoded_data.codepoint;
		encoded_string = decoded_data.decoded_string;
	}
	return result;
}
function decode_codepoint(encoded_string) {
	var result = { codepoint: "", decoded_string: "" };

	var codepoint_index = encoded_string.search("21");
	var char_count = encoded_string.substring(codepoint_index+2,...