diff --git a/src/Hydrogen.ts b/src/Hydrogen.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a6de72d304e2e243ff55a1e544fb08bff3753e2
--- /dev/null
+++ b/src/Hydrogen.ts
@@ -0,0 +1,63 @@
+import { Platform, Client, LoadStatus, createNavigation, createRouter, RoomViewModel, TimelineView, } from "hydrogen-view-sdk";
+import assetPaths from "hydrogen-view-sdk/paths/vite";
+import "hydrogen-view-sdk/style.css";
+
+export class Hydrogen {
+    private readonly _homeserver: string;
+    private _platform: Record<string, any>;
+    private _client: Record<string, any>;
+    private _urlRouter: Record<string, any>;
+    private _navigation: Record<string, any>;
+    private _container: HTMLDivElement;
+
+    constructor(homeserver: string, container: HTMLDivElement) {
+        this._homeserver = homeserver;
+        this._container = container;
+        this._platform = new Platform(container, assetPaths, {}, { development: import.meta.env.DEV });
+        this._navigation = createNavigation();
+        this._platform.setNavigation(this._navigation);
+        this._urlRouter = createRouter({ navigation: this._navigation, history: this._platform.history });
+        this._urlRouter.attach();
+        this._client = new Client(this._platform);
+    }
+
+    async register(username: string, password: string, initialDeviceDisplayName: string) {
+        let stage = await this._client.startRegistration(this._homeserver, username, password, initialDeviceDisplayName);
+        while (stage !== true) {
+            stage = await stage.complete();
+        }
+        return stage;
+    }
+
+    async login(username: string, password: string) {
+        const loginOptions = await this._client.queryLogin(this._homeserver).result;
+        this._client.startWithLogin(loginOptions.password(username, password));
+
+        await this._client.loadStatus.waitFor((status: string) => {
+            return status === LoadStatus.Ready ||
+                status === LoadStatus.Error ||
+                status === LoadStatus.LoginFailed;
+        }).promise;
+
+        if (this._client.loginFailure) {
+            throw new Error("login failed: " + this._client.loginFailure);
+        } else if (this._client.loadError) {
+            throw new Error("load failed: " + this._client.loadError.message);
+        }
+    }
+
+    async mountRoom(roomId: string) {
+        const session = this._client.session;
+        const room = session.rooms.get(roomId);
+        const vm = new RoomViewModel({
+            room,
+            ownUserId: session.userId,
+            platform: this._platform,
+            urlCreator: this._urlRouter,
+            navigation: this._navigation,
+        });
+        await vm.load();
+        const view = new TimelineView(vm.timelineViewModel);
+        this._container.appendChild(view.mount());
+    }
+}
diff --git a/src/main.ts b/src/main.ts
index c0b09b71825d701ddc4363940f5bc9b1f4113ca9..8dc447d64e47e2612107e3b16de688ec84c1f357 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,56 +1,45 @@
-import {
-    Platform,
-    Client,
-    LoadStatus,
-    createNavigation,
-    createRouter,
-    RoomViewModel,
-    TimelineView
-} from "hydrogen-view-sdk";
-import assetPaths from "hydrogen-view-sdk/paths/vite";
-import "hydrogen-view-sdk/style.css";
+import { Hydrogen } from "./Hydrogen";
+import type { IChatterboxConfig } from "./types/IChatterboxConfig";
+
+async function fetchConfig(): Promise<IChatterboxConfig> {
+    const root = document.querySelector("#chatterbox") as HTMLDivElement;
+    if (!root) {
+        throw new Error("No element with id as 'chatterbox' found!");
+    }
+
+    const configLink = root?.dataset.configLink;
+    if (!configLink) {
+        throw new Error("Root element does not have config specified");
+    }
+
+    const config: IChatterboxConfig = await (await fetch(configLink)).json();
+    return config;
+}
 
 async function main() {
-    const app = document.querySelector<HTMLDivElement>('#app')!
-    const config = {};
-    const platform = new Platform(app, assetPaths, config, { development: import.meta.env.DEV });
-    const navigation = createNavigation();
-    platform.setNavigation(navigation);
-    const urlRouter = createRouter({
-        navigation: navigation,
-        history: platform.history
-    });
-    urlRouter.attach();
-    const client = new Client(platform);
-
-    const loginOptions = await client.queryLogin("matrix.org").result;
-    client.startWithLogin(loginOptions.password("foobaraccount", "UzmiRif6UnHqp6s"));
-
-    await client.loadStatus.waitFor((status: string) => {
-        return status === LoadStatus.Ready ||
-            status === LoadStatus.Error ||
-            status === LoadStatus.LoginFailed;
-    }).promise;
-
-    if (client.loginFailure) {
-        alert("login failed: " + client.loginFailure);
-    } else if (client.loadError) {
-        alert("load failed: " + client.loadError.message);
-    } else {
-        const {session} = client;
-        // looks for room corresponding to #element-dev:matrix.org, assuming it is already joined
-        const room = session.rooms.get("!nXJtsUatHBGyIYfyYw:matrix.org");
-        const vm = new RoomViewModel({
-            room,
-            ownUserId: session.userId,
-            platform,
-            urlCreator: urlRouter,
-            navigation,
-        });
-        await vm.load();
-        const view = new TimelineView(vm.timelineViewModel);
-        app.appendChild(view.mount());
+    const root = document.querySelector("#chatterbox") as HTMLDivElement;
+    const { homeserver } = await fetchConfig();
+    const hydrogen = new Hydrogen(homeserver, root);
+    const username = generateRandomString(7);
+    const password = generateRandomString(10);
+    console.log(`Attempting to register with username = ${username} and password = ${password}`);
+    await hydrogen.register(username, password, "Chatterbox");
+    console.log("Registration done"); 
+    console.log("Attempting to login with same credentials");
+    await hydrogen.login(username, password);
+    console.log("Login successful");
+
+
+}
+
+function generateRandomString(length: number): string {
+    let result = "";
+    const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+    var charactersLength = characters.length;
+    for (let i = 0; i < length; i++) {
+        result += characters.charAt(Math.floor(Math.random() * charactersLength));
     }
+    return result;
 }
 
 main();
\ No newline at end of file
diff --git a/src/types/IChatterboxConfig.ts b/src/types/IChatterboxConfig.ts
new file mode 100644
index 0000000000000000000000000000000000000000..80f97222746a07ed24b8d781e4ae17eb1c1d733c
--- /dev/null
+++ b/src/types/IChatterboxConfig.ts
@@ -0,0 +1,4 @@
+export interface IChatterboxConfig {
+	homeserver: string;
+	auto_join_room: string;
+}
\ No newline at end of file