Open Source: A Friendly Guide for New Developers

This article is written for first-time developers — a friendly, practical introduction to help you understand open source and take your first steps.

Open source powers much of the software you use every day — from operating systems and developer tools to the websites and services you depend on. If you’re a new or first-time developer, open source is an incredible way to learn, contribute, and make real-world impact. This short guide explains what open source is, how it differs from other models, why it matters, and how you can get started.

What is Open Source?

Open source means the source code of a project is publicly available for anyone to view, modify, and distribute. This encourages transparency, peer review, and collaboration. While the code is open, projects still use licenses that define what others can do with the code.

Open Source vs Free Software vs Commercial

Before we compare them, here’s why the distinction matters: different projects have different goals and rules. Some focus on making code easy to reuse and build on, others focus on protecting users’ freedoms, and some are designed mainly to make money. That changes what you are allowed to do with the code and how the project is run.

In simple words:

  • Open source: you can see and usually modify the code — specific rights depend on the license.
  • Free software: strong emphasis on the user’s freedom to run, study, change, and share the software.
  • Commercial software: typically built to generate revenue; it may be closed-source or restricted.
Quick comparison Open Source Free Software Commercial
Main idea Code is public and reusable User freedoms are protected Built to make money (may be closed)
What you can do Read and modify (depending on license) Run, study, modify, and redistribute Often limited unless vendor permits it
Who builds it Community contributors + companies Communities and activists for software freedom Companies and paid teams
Friendly for beginners? Yes — great for learning by reading real projects Yes — teaches important values, but legal terms matter Sometimes (paid support helps), but source may be hidden

These categories overlap — for example, an open source project can also be free software, and companies often offer commercial services around open source projects.

A Brief History

The culture of sharing software predates modern open source. Key milestones include:

  • 1983: The GNU Project launched to create a free Unix-like OS.
  • 1991: Linus Torvalds released the Linux kernel, sparking widespread collaboration.
  • 2000s: Distributed version control and platforms like GitHub made contributing easier and more social.

Together these developments shaped the modern open source ecosystem: collaborative, distributed, and accessible.

Life-Changing Open Source Projects

Open source has produced tools and platforms that changed how we build software — and many are things you already use every day. You don’t have to be a developer to benefit: many smartphones include Android components that are open source, millions of websites run on WordPress, and popular apps like VLC and Firefox are open-source projects. If you’re a developer, these projects’ code is public and you can read or contribute; if not, you can still help by reporting bugs, translating, or donating.

  • Linux — the backbone of servers, mobile devices (Android), and cloud infrastructure.
  • Git — the version control system used by millions of developers.
  • Python and Node.js — languages and runtimes powering huge swathes of applications.
  • Java & Android (AOSP) — Java is a ubiquitous language used for backend systems, Android apps, and games (Minecraft was originally written in Java); Android’s open-source components power many phones and devices.
  • WordPress & Forem (dev.to) — WordPress powers a large portion of the web for blogs and sites; Forem is an open platform for developer communities and publishing — both demonstrate community-driven publishing.
  • VS Code (OSS core) — the editor’s open-source core is used widely by developers; community extensions thrive on it.
  • Firefox — a modern web browser focused on privacy and extensibility; its codebase is open and accepts contributions.
  • VLC — a versatile media player that supports countless formats and is community-driven.
  • 7-Zip — an open-source file archiver used for compressing and extracting files.
  • qBittorrent — a community-maintained BitTorrent client commonly used for peer-to-peer file sharing.
  • LibreOffice and GIMP — open alternatives for productivity and image editing.
  • OpenGL and Vulkan — graphics APIs used in games and graphics applications; they power much of the visual software you interact with.
  • Kubernetes and Docker — changed how we build, ship, and run applications.
  • Blender — open-source 3D modeling and animation software used in films and design.
  • OpenStreetMap — volunteer-built mapping data that powers many navigation and location services.

These projects are not just technologies; they’re products you’ve likely used — so the question is: if you can run them, why not read or change their code? That direct connection makes open source especially inviting for first-time contributors.

Licenses and Their Nuances

Licenses determine what others can do with your code. Choosing a license depends on your goals (encourage wide adoption, preserve freedoms, or limit certain commercial usages). Common license families:

License family Examples Key points When to choose
Permissive MIT, BSD-2/3, Apache 2.0 Minimal restrictions; Apache 2.0 adds a patent grant When you want broad adoption and easy reuse, including commercial use
Copyleft GPLv3, AGPLv3 Requires derivative works to use the same license (AGPL extends to network use) When you want derivatives to remain open-source
Source-available / Custom Business Source (e.g., MariaDB BSL), commercial dual-licensing Limits certain uses (e.g., cloud providers); may not be OSI-approved When you need specific commercial protections or staged openness

For a broader list of licenses see Open Source Initiative or the SPDX license list.

Each choice has trade-offs between adoption, control, and community expectations.

How Commercial Support Adds Value

Commercial offerings around open source help organizations use projects reliably at scale. Typical commercial services include:

  • Long-term support (LTS) and enterprise builds: stable releases with extended maintenance and security patches.
  • Service-level agreements (SLAs): guaranteed response times and dedicated support for critical incidents.
  • Managed/hosted offerings: cloud-hosted versions (e.g., MongoDB Atlas, Elastic Cloud, Redis Enterprise) that remove operational overhead.
  • Integration, consulting, and training: help with architectural design, migration, and bespoke integrations.
  • Security and compliance: coordinated security advisories, backported fixes, and assistance meeting regulatory needs.

Well-known examples include Red Hat (enterprise Linux support), MongoDB (enterprise features and Atlas), Elastic (Elastic Cloud and enterprise plugins), and Redis (Redis Enterprise and hosted services). Paid support funds maintainers and organizations, improves documentation and testing, and underwrites the work that keeps widely used projects healthy.

That said, commercial models sometimes introduce trade-offs: features may be gated behind paid tiers, or licensing changes can create tension with community expectations — so transparent governance and clear communication are important.

When Commercialization Causes Friction

Sometimes monetization strategies trigger community pushback. Here are a few concrete cases you may have heard about:

  • Vendor licensing shifts (Java/Oracle): Oracle changed the terms and long-term support model for its Oracle JDK binaries, which led many organizations to switch to community OpenJDK builds or paid commercial distributions. The change shows how vendor licensing can push users toward community-maintained alternatives (see OpenJDK: https://openjdk.java.net/).

  • Cloud-provider tensions and re-licensing (Redis, Elastic, MongoDB): Some projects moved parts of their code to more restrictive or “source-available” licenses (or SSPL-style terms) to stop cloud providers from offering managed services without sharing revenue. Those moves caused forks, ecosystem disruption, and heated debate — for example, Redis’ 2024 relicensing of certain modules and the later discussions about returning to a more permissive stance (see Redis announcement and coverage: https://redis.com/blog/introducing-redis-enterprise-modules/ and https://en.wikipedia.org/wiki/Server_Side_Public_License).

  • Platform policy changes (Chrome Manifest V2 → V3): Platform or policy changes can also affect ecosystems. Chrome’s move from Manifest V2 to Manifest V3 changed extension APIs that many ad blockers relied on, prompting privacy and developer concerns and wider discussion about platform power (see the Chromium docs and coverage: https://developer.chrome.com/docs/extensions/mv3/ and https://www.license-token.com/wiki/ublock-origin-dead-in-chrome).

These examples show why transparent governance, clear communication, and diverse funding models matter — they reduce surprises and keep communities resilient when business needs change.

How Developers Can Help Sustain Open Source

You don’t need to be a core maintainer to have high impact. Ways to help:

  • Contribute small fixes: docs, tests, or tiny bug fixes labeled “good first issue”.
  • Report clear bugs and include steps to reproduce.
  • Sponsor or donate to maintainers and organizations that support projects you rely on.
  • Help with triage and reviews to reduce maintainer burden.
  • Share knowledge: write blog posts, give talks, or mentor newcomers.

Together these actions make projects healthier and more sustainable.

Getting Started — A Simple Roadmap

A. Create your own project (learn by doing):

  1. Start small: a focused utility, library, or tool solves a real problem.
  2. Choose a license (see table above) and add a clear README.md and LICENSE file.
  3. Add CONTRIBUTING.md, issue and PR templates, and a short roadmap to guide contributors.
  4. Publish the repo (GitHub/GitLab) and announce it in relevant communities; welcome feedback.

B. Contribute to an existing project (learn from others):

  1. Pick a project you use and read its contribution guide and code of conduct.
  2. Look for labels like good first issue, help wanted, or docs.
  3. Start with documentation, tests, or small bug fixes to build context and confidence.
  4. Communicate clearly: describe your changes, link tests, and be open to reviewer feedback.

C. Be helpful, not a nuisance: small, respectful, well-explained contributions win friends. Avoid low-effort or noisy PRs and follow the project’s contribution norms — a good reminder is this tongue-in-cheek example: https://www.reddit.com/r/ProgrammerHumor/comments/1o0iqf6/lookingclosely/.

Open source is welcoming — start small and grow your impact over time.

Conclusion

Open source offers an incredible way for new developers to learn, contribute, and shape software used around the world. Start small, be consistent, and you’ll find that helping others also accelerates your own growth.

Email or Website Summarization Browser Extension

Browser Extensions

Continuing on the journey of browser extension, lets see how a browser extension can help with Email or Website summarization using a Generative AI API integration.

I used NodeJS as my backend to create a API based on VertexAI for summarization. Here is the a documentation to create an API using VertexAI.

Now getting into extension development, basic development content is already available in the blog post here and the important part if the popup.js and content.js

popup.js

document.getElementById("summarizeEmail").addEventListener("click", () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, { action: "getEmailContent" }, (response) => {
if (response.emailContent) {
chrome.runtime.sendMessage({ action: "summarizeEmail", emailContent: response.emailContent }, (response) => {
document.getElementById("summary").innerText = response.summary;
});
}
});
});
});

document.getElementById("summarizeText").addEventListener("click", () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.scripting.executeScript(
{
target: { tabId: tabs[0].id },
function: getSelectedText,
},
(results) => {
if (results && results[0] && results[0].result) {
chrome.runtime.sendMessage({ action: "summarizeText", textContent: results[0].result }, (response) => {
document.getElementById("summary").innerText = response.summary;
});
}
}
);
});
});

function getSelectedText() {
return window.getSelection().toString();
}

content.js

// Function to inject the "AI Summary" button into Gmail
const injectAISummaryButton = () => {
const existingButton = document.getElementById("ai-summary-button");
if (existingButton) {
return; // Button already exists, do not add it again
}

const targetElement = document.querySelector(".AO");
if (targetElement) {
const aiSummaryButton = document.createElement("button");
aiSummaryButton.id = "ai-summary-button";
aiSummaryButton.innerText = "AI Summary";
aiSummaryButton.style.position = "absolute";
aiSummaryButton.style.top = "10px";
aiSummaryButton.style.right = "10px";
aiSummaryButton.style.zIndex = 10000;
aiSummaryButton.style.backgroundColor = "#007bff";
aiSummaryButton.style.color = "#ffffff";
aiSummaryButton.style.border = "none";
aiSummaryButton.style.padding = "10px";
aiSummaryButton.style.cursor = "pointer";

aiSummaryButton.addEventListener("click", () => {
const emailContent = getEmailContent();
if (emailContent) {
chrome.runtime.sendMessage({ action: "summarizeEmail", emailContent: emailContent }, (response) => {
showAISummaryOverlay(response.summary);
});
}
});

targetElement.prepend(aiSummaryButton);
}
};

// Function to extract email content from Gmail's DOM
const getEmailContent = () => {
const emailContentElement = document.querySelector(".AO"); // Selector for the email body content
return emailContentElement ? emailContentElement.innerText : "";
};

// Function to create and show the AI Summary overlay
const showAISummaryOverlay = (summary) => {
// Remove existing overlay if present
const existingOverlay = document.getElementById("ai-summary-overlay");
if (existingOverlay) {
existingOverlay.remove();
}

// Create overlay elements
const overlay = document.createElement("div");
overlay.id = "ai-summary-overlay";
overlay.style.position = "fixed";
overlay.style.top = "0";
overlay.style.left = "0";
overlay.style.width = "100%";
overlay.style.height = "100%";
overlay.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
overlay.style.zIndex = 10000;
overlay.style.display = "flex";
overlay.style.alignItems = "center";
overlay.style.justifyContent = "center";

const content = document.createElement("div");
content.style.backgroundColor = "white";
content.style.padding = "20px";
content.style.borderRadius = "10px";
content.style.maxWidth = "500px";
content.style.boxShadow = "0 0 10px rgba(0, 0, 0, 0.5)";

const title = document.createElement("h2");
title.innerText = "AI Summary";
title.style.marginTop = "0";

const summaryText = document.createElement("p");
summaryText.innerText = summary;

const closeButton = document.createElement("button");
closeButton.innerText = "Close";
closeButton.style.marginTop = "20px";
closeButton.style.padding = "10px";
closeButton.style.backgroundColor = "#007bff";
closeButton.style.color = "white";
closeButton.style.border = "none";
closeButton.style.borderRadius = "5px";
closeButton.style.cursor = "pointer";

closeButton.addEventListener("click", () => {
overlay.remove();
});

// Append elements
content.appendChild(title);
content.appendChild(summaryText);
content.appendChild(closeButton);
overlay.appendChild(content);
document.body.appendChild(overlay);
};

// Inject the "AI Summary" button when the content script is loaded
injectAISummaryButton();

// Observe changes in the Gmail DOM to inject the button when necessary
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === "childList") {
injectAISummaryButton();
}
}
});

observer.observe(document.body, { childList: true, subtree: true });

// Listen for messages from the popup or background script
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "getEmailContent") {
const emailContent = getEmailContent();
sendResponse({ emailContent: emailContent });
}
});

background.js

const API_ENDPOINT = "http://localhost:3001/secure/ai";

const getSummary = (content, callback) => {
const encodedContent = encodeURIComponent(content);

fetch(API_ENDPOINT + "/summary", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ prompt: "Please summarize the below uri encoded content. \n\n" + content }),
})
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok " + response.statusText);
}
return response.json();
})
.then((data) => {
if (callback && typeof callback === "function") {
callback(data);
}
})
.catch((error) => {
console.error("Error: " + error);
if (callback && typeof callback === "function") {
callback({ summary: "Error fetching summary." });
}
});
};

chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "summarizeText",
title: "AI Summary",
contexts: ["selection"],
});
});

chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "summarizeText") {
const selectedText = info.selectionText;

console.log("Selected Text: " + selectedText);

getSummary(selectedText, (data) => {
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: (summary) => {
const summaryElement = document.createElement("div");
summaryElement.style.position = "fixed";
summaryElement.style.bottom = "10px";
summaryElement.style.right = "10px";
summaryElement.style.backgroundColor = "white";
summaryElement.style.border = "1px solid black";
summaryElement.style.padding = "10px";
summaryElement.style.zIndex = 10000;
summaryElement.innerText = summary;
document.body.appendChild(summaryElement);
},
args: [data.message],
});
});
}
});

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "summarizeEmail") {
const selectedText = request.emailContent;

console.log("Selected Email Content: " + selectedText);

getSummary(selectedText, (data) => {
sendResponse({ summary: data.message });
});

return true; // Will respond asynchronously.
}
});

Explanation on whats happening,

  1. Listen to the gmail page for the page loads, Once the page is loaded invoke the injectAISummaryButton in the content.js
  2. “AI Summary button will be injected at the top right corner of the page”
  3. A context menu is also added when a text is selected. The click event i registered in the popup.js.
  4. Upon selecting the text in any web page and clicking on the context menu. or clicking on the “AI Summary” on gmail page will send the data of the email over the api and show the summarized response to the user.

Refer the full chrome extension plugin at GitHub

Browser extension sample – Chrome/Edge – HttpRequestViewer

Browser Extensions

The Evolution of Browser Extensions: From Web Customization to Advanced Development Tools – Part 2
We discussed about The evolution of the Browser extensions in the previous post. Lets quick learn how to create a Chrome/Edge/Firefox extension. I have mentioned “Advanced development tools” in the title, but never got chance to explore those capabilities earlier. We will create a simple extension to explore the power of it.

Creating a browser extension has never been easier, thanks to the comprehensive documentation and support provided by browser vendors. Below, we’ll walk through the steps to create a simple extension for both Chrome and Microsoft Edge using Manifest V3. We will use this tool to print the list of HTTP requests that are fired in a given browser and list it in the page.

Basics of extensions:

Manifests – A manifest is a JSON file that contains metadata about a browser extension, such as its name, version, permissions, and the files it uses. It serves as the blueprint for the extension, informing the browser about the extension’s capabilities and how it should be loaded.

Key Components of a Manifest File:

Here are the key components typically found in a Manifest V3 file:

1. Manifest Version: There are different versions of the manifest file, with Manifest V3 being the latest and most widely adopted version. Manifest V3 introduces several changes aimed at improving security, privacy, and performance with lot of controversies around it. Read more about the controversies at Ghostery.
2. Name and Version: These fields define the name and version of the extension. Choose a unique name and version. An excellent guide of version semantics is available here.
3. Description: A short description of the extension’s functionality.
4. Action: Defines the default popup and icon for the browser action (e.g., toolbar button).
5. Background: Specifies the background script that runs in the background and can handle events like network requests and alarms.
6. Content Scripts: Defines scripts and stylesheets to be injected into matching web pages.
7. Permissions: Lists the permissions the extension needs to operate, such as access to tabs, storage, and specific websites.
8. Icons: Specifies the icons for the extension in different sizes. For this post I created a simple icon using Microsoft Designer. I gave a simple prompt with the description above and I got the below image. Extension requires different sizes for showing it in different places. I used Chrome Extension Icon Generator and generated different sizes as needed.

     

9. Web Accessible Resources: Defines which resources can be accessed by web pages.

Create a project structure as follows:

HttpRequestViewer/
|-- manifest.json
|-- popup.html
|-- popup.js
|-- background.js
|-- history.html
|-- history.js
|-- popup.css
|-- styles.css
|-- icons/
    |-- icon.png
    |-- icon16.png
    |-- icon32.png
    |-- icon48.png
    |-- icon128.png

Manifest.json

{
  "name": "API Request Recorder",
  "description": "Extension to record all the HTTP request from a webpage.",
  "version": "0.0.1",
  "manifest_version": 3,
  "host_permissions": [""],
  "permissions": ["activeTab", "webRequest", "storage"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icons/icon.png"
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icons/icon16.png",
    "32": "icons/icon32.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self';"
  },
  "web_accessible_resources": [{ "resources": ["images/*.png"], "matches": ["https://*/*"] }]
}

popup.html
We have two options with the extension.

1. A button with record option to start recording all the HTTP requests
2. Link to view the history of HTTP Requests recorded

<!DOCTYPE html>
<html>
  <head>
    <title>API Request Recorder</title>

    <link rel="stylesheet" href="popup.css" />
  </head>
  <body>
    <div class="heading">
      <img class="logo" src="icons/icon48.png" />
      <h1>API Request Recorder</h1>
    </div>
    <button id="startStopRecord">Record</button>

    <div class="button-group">
      <a href="#" id="history">View Requests</a>
    </div>

    <script src="popup.js"></script>
  </body>
</html>

popup.js
Two event listeners are registered for recording (with start / stop) and viewing history.
First event is used to send a message to the background.js, while the second one instructs chrome to open the history page in new tab.

document.getElementById("startStopRecord").addEventListener("click", () => {
  chrome.runtime.sendMessage({ action: "startStopRecord" });
});

document.getElementById("history").addEventListener("click", () => {
  chrome.tabs.create({ url: chrome.runtime.getURL("/history.html") });
});

history.html

 
<!DOCTYPE html>
<html>
  <head>
    <title>History</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1>History Page</h1>
    <table>
      <thead>
        <tr>
		  <th>Method</th>
          <th>URL</th>
          <th>Body</th>
        </tr>
      </thead>
      <tbody id="recorded-data-body">
        <!-- Data will be populated here -->
      </tbody>
    </table>
    <script src="history.js"></script>
  </body>
</html>

history.js
Requests background.js to “getRecordedData” and renders the result in the html format.

document.addEventListener("DOMContentLoaded", () => {
  chrome.runtime.sendMessage({ action: "getRecordedData" }, (response) => {
    const tableBody = document.getElementById("recorded-data-body");
    response.forEach((record) => {
      const row = document.createElement("tr");
      const urlCell = document.createElement("td");
      const methodCell = document.createElement("td");
      const bodyCell = document.createElement("td");

      urlCell.textContent = record.url;
      methodCell.textContent = record.method;
      bodyCell.textContent = record.body;

      row.appendChild(methodCell);
      row.appendChild(urlCell);
      row.appendChild(bodyCell);
      tableBody.appendChild(row);
    });
  });
});

background.js
Background JS works as a service worker for this extension, listening and handling events.
The background script does not have access to directly manipulate the user page content, but can post results back for the popup/history script to handle the cosmetic changes.

let isRecording = false;
let recordedDataList = [];

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  console.log("Obtined message: ", message);
  if (message.action === "startStopRecord") {
    if (isRecording) {
      isRecording = false;
      console.log("Recording stopped...");
      sendResponse({ recorder: { status: "stopped" } });
    } else {
      isRecording = true;
      console.log("Recording started...");
      sendResponse({ recorder: { status: "started" } });
    }
  } else if (message.action === "getRecordedData") {
    sendResponse(recordedDataList);
  } else {
    console.log("Unhandled action ...");
  }
});

chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    if (isRecording) {
      let requestBody = "";
      if (details.requestBody) {
        if (details.requestBody.formData) {
          requestBody = JSON.stringify(details.requestBody.formData);
        } else if (details.requestBody.raw) {
          requestBody = new TextDecoder().decode(new Uint8Array(details.requestBody.raw[0].bytes));
        }
      }
      recordedDataList.push({
        url: details.url,
        method: details.method,
        body: requestBody,
      });
      console.log("Recorded Request:", {
        url: details.url,
        method: details.method,
        body: requestBody,
      });
    }
  },
  { urls: [""] },
  ["requestBody"]
);

Lets load the Extension

All set, now lets load the extension and test it.

  • Open Chrome/Edge and go to chrome://extensions/ or edge://extensions/ based on your browser.
  • Enable “Developer mode” using the toggle in the top right corner.
  • Click “Load unpacked” and select the directory of your extension.

Load extensionupload extension

  • Your extension should now be loaded, and you can interact with it using the popup.
  • When you click the “Record” button, it will start logging API requests to the console.

  • Click the “Record” button again and hit the “View requests” link in the popup to view the history of APIs.

I have a sample page (https://itechgenie.com/demos/apitesting/index.html) with 4 API calls, which also loads images based on the API responses. You could see all the API requests that is fired from the page including the JS, CSS, Images and API calls.


Now its up to the developers imagination to build the extension to handle these APIs request and response data and give different experience.

Code is available in GitHub at HttpRequestViewer

The Evolution of Browser Extensions: From Web Customization to Advanced Development Tools

Browser Extensions

It’s been a while that I published a post. A week before, I created a new Chrome extension and shared with my team and noticed the new developers didn’t have knowledge on how powerful the browser extensions can be. It pushed me to write a short post about the history and power of browser extensions.

A Brief History

Browser extensions have dramatically transformed how users interact with the internet, offering a plethora of customization options and functionalities that enhance productivity, security, streamline workflows and user experience. These small software modules, integrated into web browsers like Chrome, Edge, Firefox etc., enable users and developers to tailor their browsing experience, automate tasks, and access additional features not available in standard browser installations. The evolution of browser extensions has marked a significant milestone in web development, fostering a community of developers who continuously innovate and simplify complex tasks.

The Early Days

Browser extensions trace their origins back to the early days of web browsers. The first notable implementation was by Internet Explorer in the late 1990s, which allowed for basic plugins to extend browser capabilities. Early days of these extensions allowed developers to add custom menu bars(also known as Browser Bands and Communication Bands), context menu options for seamless integration with extensions. CricInfo cricket score ticker was a popular toolbar that I have used in the early days. Internet download manager extension is one another toolbar which allowed the download of audios and videos, changed the life of lot of Dial-up connection users.

The Rise of Firefox

However, it was Mozilla Firefox that popularized the concept of extensions by providing a dedicated platform for the developers to create and submit the add-ons. Themes and skins are a fun part of extensions world. Greasemonkey,one of the early add-ons, allowed users to write custom code on top of extensions was a boon for customization. I used my first AdBlocker script from UserScripts.org installed using Greasemonkey. This Add-on allowed me to create customize my own scripts without taking the hassle of publishing. Firefox’s various components like Add-ons, Extensions, and Plugins (Flash, Java, SilverLight, etc.) eventually evolved into standardized extensions.

The Chrome Era

Then came the days of Chrome. Google Chrome, introduced in 2008, revolutionized the extension landscape by offering streamlined APIs and a dedicated web store for its extensions. This facilitated easier development and distribution of extensions, leading to a surge in their popularity. The Chrome Web Store, launched in 2010, became a central hub for users to discover and install extensions, further solidifying their importance in the web ecosystem.

Extensions like Web Developer and React Developer Tools provide essential utilities for debugging, testing, and optimizing web applications. By leveraging browser APIs, developers can create tools that integrate seamlessly into their development environment, automating repetitive tasks and offering real-time insights into application performance.

Essential Extensions for Users

Some of the most used extensions include:
AdBlock / AdBlock Plus / uBlock Origin: Blocks ads on websites, improving load times and reducing clutter.
Microsoft Editor / Grammarly: Enhances writing by checking grammar, spelling, and style.
Honey: Automatically finds and applies coupon codes at checkout.
Bitwarden / LastPass: A password manager that stores and auto-fills passwords securely.
Momentum: Replaces the new tab page with a personal dashboard featuring a to-do list, weather, and inspirational quotes.
Dark Reader: Applies a dark theme to websites, reducing eye strain.

Must-Have Extensions for Developers

From a developer’s perspective, extensions are a boon. Some popular developer-friendly extensions are:
TamperMonkey – Modify website layouts, add/remove features, or automate actions – Alternative to Greasemonkey supporting userscripts.
React Developer Tools / Vue.js / – Provides debugging and inspection tools for React and Vue.js applications.
Redux DevTools – Allows developers to inspect every state and action payload for Redux applications.
Postman – A powerful tool for testing APIs by making HTTP requests.
JSON Viewer – Formats JSON data to make it more readable.
XPath Helper – Helps to find XPath expressions for elements on a webpage.
ColorZilla – Advanced color picker and gradient generator.
WhatFont – Identifies fonts used on a webpage.

We will see how to create a simple browser extension in the next post –Browser extension sample – Chrome/Edge – HttpRequestViewer

Must have Android apps for developers (Non Android developers)

The below list of apps are note rated or ordered in any ways.

1. AndroIRC – An IRC client application
2. Chrome – Mobile browser
3. Mozilla Firefox – Mobile browser
4. SSH/SFTP Server – Exposing your mobile as a SSH/SFTP server
5. AndFTP – FTP client
6. JuiceSSH – SSH client
7. aLogcat/aLogrec – Logger apps to view or save Android logs
8. Network Info II – Shows info about the phone and the current network, Bluetooth, IPv6 and Cell connection
9. kWS – Android Web Server
10. Google Analytics – Mobile client for Google Analytics
11. WordPress – Mobile client for WordPress dashboard
12. Control Panel for cPanel – Mobile client for cPanel Dashboard
13. File Expert – All in one File manager supporting Windows Samba, FTP, SFTP, FTPS, Webdev, Bluetooth OBEX client

Note: The above app list is used by me and has nothing to do with the other users.

Famous Short URL services

URL shortening is a technique used to make the URLs substantially shorter in length and still direct to the required page. This is achieved by using an HTTP Redirect on a domain name that is very short in length, which links to the web page that has a long URL.

URL shortening is also used for beautify a link, track the url activity, in some cases to used to disguise the underlying address for legitimate purposes.

Some of the famous URL shortening services are follows:

1. Adf.ly
2. Bit.ly
3. Goo.gl
4. Is.gd
5. Tinyurl.com
6. V.gd

Create Web Services using Axis Java2WSDL, WSDL2Java and Eclipse for all Servers manually – Part 2

With all the basic configurations done as specified in the last Article we continue to develop the Business logic.

  1. Create a class named Calculator.java, place four public methods add, subtract, multiply and delete and place the appropriate logics in it.
    package com.itechgenie.services.impl;
    public class Calculator {
    	public int add(int a, int b) {
    		return a+b  ;
    	}
    
    	public int subtract(int a, int b) {
    		return a-b ;
    	}
    
    	public int multiply(int a, int b) {
    		return a * b ;
    	}
    
    	public int divide(int a, int b) throws ArithmeticException {
    		return a /b ;
    	}
    }
  2. This is the class that has to be exposed as the Web Service and we write the funky TestRunner.java class to do all out operations like creating WSDL file, creating stub file etc.
  3. Generate WSDL file using Java2WSDL: Axis has a tool called Java2WSDL, which generates a WSDL file for a web service using a Java class. Java2WSDL file takes the following arguments.
    1. o – name for WSDL file -> calculator.wsdl
    2. n – target namespace -> mx:com.itechgenie.services.Calculator
    3. l – url of web service -> http://<host:port>/<Project-Name>/services/calculator

    Summing up the above arguments the following command line arguments is created.

    String java2wsdlArgs[] = {"-ocalculator.wsdl", "-nmx:com.itechgenie.services.Calculator", "-v", "-lhttp://localhost:8080/axis/services/calculator", "com.itechgenie.services.Calculator"} ;

    Read this Article on how to run the command line java tools from Eclipse.
    You can run the Java2WSDL as follows in the TestRunner class. Naah, don’t ask how, just put the following lines the main method and press CTRL + F11.

    try {
    	Java2WSDL.main(java2wsdlArgs) ;
    } catch (Exception e) {
    	e.printStackTrace() ;
    }

    The Java2WSDL class has the System.exit(0); method called from inside. So lines after the Java2WSDL will not be executed. To get the other arguments supported you can just run Java2WSDL.main(new String[0]) ;. This will display all the arguments supported by Java2WSDL Utility and this works for other utilities also.
    After running this Utility you will find the calculator.wsdl file created in the root folder of the Project.

  4. Generate Server side and Client side codes using WSDL2Java: WSDL2Java is another tools provided by the AXIS, which can generate server side and client side Java classes using a WSDL file. These classes are needed for deploying the web service and also for accessing the web service using a Java client. This tool expects the following argument which includes the WSDL file generated in the last step.
    1. o – output folder -> src
    2. p – package for generated classes -> mx:com.itechgenie.services. generated
    3. s – generate server side classes as well
    4. *.wsdl – WSDL file of any web service

    Summing up the above arguments the following command line arguments is created.

    String wsdl2javaArgs[] = {"-osrc", "-pcom.itechgenie.generated.service", "-s", "calculator.wsdl", "-v"} ;

    Read this Article on how to run the command line java tools from Eclipse.
    Now run the WSDL2Java utility as follows.

    try {
    	WSDL2Java.main(wsdl2javaArgs) ;
    } catch (Exception e) {
    	e.printStackTrace() ;
    }

    Once the above command is run, Just refresh the project in eclipse, you will find the following files created inside the “com.itechgenie.generated.service” package.

    1. Calculator.java
    2. CalculatorService.java
    3. CalculatorServiceLocator.java
    4. CalculatorSoapBindingImpl.java
    5. CalculatorSoapBindingStub.java
    6. deploy.wsdd
    7. undeploy.wsdd

    The above files can be used in both Server and Clients side as Skeleton (CalculatorSoapBindingImpl.java) and the Stub (CalculatorSoapBindingStub.java) respectively.

  5. Binding the business logic with the Skeleton: Take the Skeleton file and you will find the exact methods that were available in our Business logic class (Calculator.java.).
    Create a instance of the Business class and invoke the appropriate method from the skeleton as follows (Find the lines highlighted in yellow.).

    package com.itechgenie.generated.service;
    
    import com.itechgenie.services.Calculator;
    
    public class CalculatorSoapBindingImpl implements com.itechgenie.generated.service.Calculator{
    
    	Calculator calculatorImpl = new Calculator() ;
    
        public int add(int in0, int in1) throws java.rmi.RemoteException {
        	return calculatorImpl.add(in0, in1) ;
        }
    
        public int subtract(int in0, int in1) throws java.rmi.RemoteException {
        	return calculatorImpl.subtract(in0, in1) ;
        }
    
        public int divide(int in0, int in1) throws java.rmi.RemoteException {
        	return calculatorImpl.divide(in0, in1) ;
        }
    
        public int multiply(int in0, int in1) throws java.rmi.RemoteException {
        	return calculatorImpl.multiply(in0, in1) ;
        }
    
    }

    That’s it; we are now done with the development part of the Web Service. All we have to do is to configure to make the service up and running.

  6. Last configurations to make our service available: Open the server-config.wsdd file inside the WEB-INF folder. You will find the following lines.
      <!--  Your Service from the deploy.wsdd file - Starts here -->
    
      <!--  Your Service from the deploy.wsdd file - Ends here -->

    Keep the file aside and open the deploy.wsdd from the WSDL2Java generated files. Copy the <service> … </service> tag completely and paste in between the comments said above.

  7. Conclusion: You can follow the steps 6 to 11 and create as many services as you want and paste them in the server-config.wsdd.
    With this the configurations for the Web Service is over. Export the Project as a War and deploy it in Web Server and point to the URL http://<host:port>/<Project-Name>/services
  8. This URL should display all the services generated from steps 6 to 11 with the links the WSDL files for the above.

    Click here to download the sample project.

Create Web Services using Axis Java2WSDL, WSDL2Java and Eclipse for all Servers manually – Part 1

There a lot of Web Service implementations available in market. The most widely used among them is the Axis way of implementation. There are a lot of Examples available in the web to create expose, consume the Web services using the Axis packages. But it is not feasible to work get the Axis complete packages inside corporate offices all of a sudden and yes I faced the same situation.

After some investment of time I found some funky stuff in web to create a Web Service with just a couple of jars in hand and off-course with the help of Eclipse.

Prerequisites:

  1. Eclipse, any version should be ok, but I was using the Eclipse Indigo with Ant installed in it.
  2. The set of jars needed. Jars are included in the Project sample.
    1. axis.jar
    2. commons-discovery-0.2.jar
    3. commons-logging.jar
    4. jaxrpc.jar
    5. log4j-1.2.15.jar
    6. saaj.jar
    7. wsdl4j.jar
    8. The sample web.xml, server-config.wsdd (These will be used later in the development steps).

Steps to develop Web Services:

  1. Create a Dynamic Web Project “SampleWebService” in Eclipse.
  2. Place the above said jars in the WEB-INF/jars folder.
  3. Open the Web.xml file and copy the following contents into it somewhere between tags. These contents are available in the sample attached.
      <servlet>
        <display-name>Apache-Axis Servlet</display-name>
        <servlet-name>AxisServlet</servlet-name>
        <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>/servlet/AxisServlet</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>*.jws</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
      </servlet-mapping>
      <servlet>
        <display-name>Axis Admin Servlet</display-name>
        <servlet-name>AdminServlet</servlet-name>
        <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
        <load-on-startup>100</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>AdminServlet</servlet-name>
        <url-pattern>/servlet/AdminServlet</url-pattern>
      </servlet-mapping>
  4. Copy the server-config.wsdd next to web.xml file. We will reuse this file once again after complete the business logic of the server.
  5. Now the basic configurations are complete, we have to develop the business logic for the Web Service. In my example I have taken the Old school Calculator sample.
    Click here to go to the next Part of this article.

Top things to look at before developing a Web Site – Part 2

  1. Web Hosting: Once the domain name is selected the hosting account has to be selected. There are different hosting types available. Most commonly used hosting is Shared web hosting. Even though the Free web hosting is used most of the users prefer the Shared hosting and VPS hosting. Beginners can start with a free web hosting account and go for the Shared and the VPS hosting types based on the budgets.
  2. Development tools: After all the above elicitationsare done the development process can be started. The below tools can be used to make the development faster.
    1. Search domain name here and check if it is already registered. If it’s already registered the site might display set of alternative domain names available.
    2. Set up a local environment and test your website. Use XAMPP, IIS, Tomcat to setup Local environments with PHP, .Net, Java languages respectively.
    3. Use Komposer, Amaya to develop the PHP type websites. Obviously only the Visual Studio is used to develop .Net type websites. I prefer using the Eclipse and its plugins to develop the PHP and Java type sites. They provide a very good interface to design, develop and test, integrating with the Local servers.
    4. Use FTP clients like Filezilla, Net2Ftp to upload the tested local files to the web servers.
    5. Many Open source tools that are alternative to the proprietary software are available Here and Here.
  3. CMS tools: Instead of developing a whole website from scratch, there are a lot of Content Management Systems available in the market to make the development time easier and faster. Some commonly used CMS tools are WordPress, Joomla, Drupal etc. The WordPress is most widely used CMS for blogging. Similarly select a tool to that suits the site type.
  4. Testing for Browser support: Once the development of the site is completed the testing phase comes in place. Even though the testing is one of the Development Life Cycle step, the Browser support check is a most important thing to deliver your website to your clients as you wish them to be. This is one of the important advantages when using the CMS tools. Because the development community takes care of all these things so that you don’t need to put your time in. The IE Tester is used to check test the website display in the Internet Explorer versions from IE6 to IE10 While writing this article. Alternatively there are a lot of online tools to do the same. The Browsershot.com takes the screen shots of the website in all the versions of the browsers including different operating system.
  5. Get noticed: After all the above said steps, it is very important to get your site to viewers to whom it is intended to be. This set is commonly known as Search Engine Optimization (SEO). The SEO plays a very important role in making your website popular. I Intent to write a separate article on SEO. But I am placing a simple step to start the SEO.
    1. Submit your site to popular Search engines like Google, Bing.
    2. Once the site is placed the search engine will index the site from there on. As your site’s content becomes unique and popular they will be shown in the search results and visitors will start pouring in.

Top things to look at before developing a Web Site – Part 1

  1. Content Type (Static or Dynamic): The First and foremost thing a Web developer must look at is the “Content type”. Take a justified side between static and dynamic content when you go for the web site. If the site contains only a 5 to 10 pages with just few contents that may not have new change then the web site will be a Static that does not need much of server side support. But if you go for a site with Dynamic contents what may change in time and needs customization then you are onto a Dynamic site which needs immense Server support. Most of the sites now days are dynamic contents which need the servers support.
  2. Development Language: The Language in which you are going to develop the site is very important after selecting the content type. The widely used Language or the scripting for the web developing is PHP. Other famous technologies .Net, Java, Python, Perl etc. Every language has its own pros and cons. The developing languages have to be selected as per the need and knowledge. Usually scripting languages are easier to learnt and develop faster for beginners.
  3.  Web Servers: The web servers are the next thing we should care about. All the Web servers support the static content sites with just the HTML contents in it. When we look for the Server side scripting the Web Servers play a major role in providing the support for them. Web servers can be selected based on the Language by which you wanted to develop the websites. Even though the web servers can support any of the language with a set of customization, it’s better to go for a Web server which can natively support your development Language.  Because usually the customization never comes with less cost. Here are the widely used Web servers in market.
    1. Apache – For PHP natively and with Java support
    2. IIS – For .Net natively and PHP and Java support
    3. Tomcat – For Java natively and PHP support
  4. Domain name: The domain name is the one which is going to show up your stuffs to the World. They play a very important role and they are the entry point that visitors use to view your website on the web. The domain name can be of any length, but my personal opinion is to keep it as simple as possible and less than 8 characters. Choose a domain name that is very relevant to your site content, short, simple, crisp and easy to remember. If you could not specify your theme in just a work keep an abbreviation of the theme as domain name.
  5. Selecting a TLD: A top-level domain (TLD) is one of the domains at the highest level in the hierarchical Domain Name System of the Internet. In other words, the domain names ends with the extensions like .com, .edu, .org, .web, .net etc which are knows as TLDs. Select a TLD which is related to your Site theme, locations and other factors.
    1. Examples: If your site is related to education, select TLD as .edu, If yours is a big Organization select .org, if the service you provide is country specific then select a country level TLD like .us, .ca, .in, .ph, co.in, .co.ca, co.in etc.
    2. Make sure you select a reasonable TLD and also consider the cost factors. Some TLDs are very costlier.
    3. If you could not find a specific TLD for your site theme just select the .com, which is most widely used.