Parse JSON Files in the Browser (100% Client Side). Lightweight Vanilla JavaScript (~30 lines of code).
Copy and paste the code (below) and paste it directly into the browser console. If the code was injected successfully, drag & drop one or more JSON files anywhere. Results are logged to the console
a) Wrap it in HTML <script> tags
b) Save it as a .js file and load it externally 
c) Adapt it to work as a userscript (for browser extension like tampermonkey & greasemonkey)
No special permissions or dependencies required.
Once loaded, simply drag & drop one or more JSON files anywhere on the page. 
On success, parsed JSON data should be logged to the developer console. Feel free to customize it there.
Tested on a modern version of Firefox on Windows. At the moment, I'm not concerned about cross-browser compatibility since it suits my needs, but let me know if you run into issues. I might be able to help.
Tip: Need to parse the whole list before moving on? Adapting this script to use promise.all() should be fairly straight forward.
(() => {
const fileToString = (inputFile) => {
	const fr = new FileReader();
	return new Promise((resolve, reject) => {
		fr.onerror = () => { fr.abort(); reject(new DOMException("Problem parsing input file."));} //handle file read error
		fr.onload = () => resolve(fr.result); //resolve promise once the file is loaded
		fr.readAsText(inputFile); //read the file as plain text. On success, the promise resolves, passign the result back to the dropHandler function
})}
const dropHandler = async (e) => {
	e.preventDefault(); //disable default drop behavior
  for await (let file of e.dataTransfer.files) { //loop through dropped files
	try {
		let name = file.name.replace(".json","");
		const str = await fileToString(file); //convert dropped file to string
		const data = await JSON.parse(str); //convert file string to json
		console.log({name,data});  /*do stuff with the JSON data*/
	} catch (err) {console.log({err})}
   }}
window.ondragover = (e) => e.preventDefault(); //Prevent default browser behavior
window.ondrop = (e) => dropHandler(e); //Handle dropped files
})();(() => {
const fileToString = (inputFile) => {
	const fr = new FileReader();
	return new Promise((resolve, reject) => {
		fr.onerror = () => { fr.abort(); reject(new DOMException("Problem parsing input file."));} //handle file read error
		fr.onload = () => resolve(fr.result); //resolve promise once the file is loaded
		fr.readAsText(inputFile); //read the file as plain text. On success, the promise resolves, passign the result back to the dropHandler function
})}
const dropHandler = async (e) => {
	
	e.preventDefault(); //disable default drop behavior
  for await (let file of e.dataTransfer.files) { //loop through dropped files
	try {
		const t0 = performance.now();	
		let name = file.name.replace(".json","");
		const str = await fileToString(file); //convert dropped file to string
		const data = await JSON.parse(str); //convert file string to json
		const t1 = performance.now();
		const parseTime = `${t1 - t0} milliseconds.`;
		console.log({name,data,parseTime});  /*do stuff with the JSON data*/	
	} catch (err) {console.log({err})}
 }}
window.ondragover = (e) => e.preventDefault(); //Prevent default browser behavior
window.ondrop = (e) => dropHandler(e); //Handle dropped files
})();Supported File Types: json,csv,txt
Note: txt files must be delimited by one of the following (ordered by priority):
	1) lines:  "\n"
	2) tabs:   "\t"		
	3) commas: ","
(() => {
	
	var options = {
		scripts: ["https://d3js.org/d3.v5.min.js"]
	}
const fileToString = (inputFile) => {
	const fr = new FileReader();
	return new Promise((resolve, reject) => {
		fr.onerror = () => { fr.abort(); reject(new DOMException("Problem parsing input file."));} //handle file read error
		fr.onload = () => resolve(fr.result); //resolve promise once the file is loaded
		fr.readAsText(inputFile); //read the file as plain text. On success, the promise resolves, passign the result back to the dropHandler function
})}
const dropHandler = async (e) => {
	e.preventDefault(); //disable default drop behavior
  for await (let file of e.dataTransfer.files) { //loop through dropped files
	try {
		const str = await fileToString(file); //convert dropped file to string
		let format = file.name.slice(file.name.lastIndexOf(".")+1); //get assumed format from file name
		var name = file.name.replace("."+format,"");
		if(format == "json"){
			var data = await JSON.parse(str); //convert file string to json
		}else if(format == "txt"){
			var hasLines = str.indexOf("\n") > -1;
			var hasComma = str.indexOf(",") > -1;
			var hasTab = str.indexOf("\t") > -1;
			if(hasLines){
				var data = await str.split("\n"); //split line-delimited list
			} else if(hasTab){
					var data = await str.split("\t"); //split tab-delimited list
			}	else if(hasComma){
					var data = await str.split(","); //split comma-delimited list
			} 
		}else if(format == "csv"){
			var data = await d3.csvParse(str) //convert csv string to json
		}
		console.log({name,format,data});  /*do stuff with the JSON data*/	
	} catch (err) {console.log({err})}
 }}
 
window.ondragover = (e) => e.preventDefault(); //Prevent default browser behavior
window.ondrop = (e) => dropHandler(e); //Handle dropped files
const loadScripts = (scripts) => {
	console.log(`Loading External Scripts`);
	var scriptCountdown = scripts.length;
	var loadScript = (url) => {
		var scriptsLoaded = () => {
			console.log({scriptsLoaded:scriptCountdown});
			scriptCountdown == 0 ? console.log("External scripts loaded. Ready to parse!") : null;
			return true;
		}
		console.log("loadScript",{url})
		var imported = document.createElement('script');
				imported.src = url;
				imported.addEventListener("load", () => {
					scriptCountdown--;
					scriptsLoaded();
				});
				document.head.appendChild(imported);
	}
	scripts.forEach(loadScript)
}
loadScripts(options.scripts);
})();