diff --git a/src/client/.gitkeep b/src/client/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/client/auth.ts b/src/client/auth.ts
new file mode 100644
index 0000000000000000000000000000000000000000..81dff37dae8fc798967691078c55f04c1fcbe1ba
--- /dev/null
+++ b/src/client/auth.ts
@@ -0,0 +1,42 @@
+import Axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
+import { EmptyReq, LoginReq, RegisterReq, UserResponse } from './types';
+
+type LoginQuery = (data?: LoginReq) => Promise<AxiosResponse<UserResponse>>;
+type RegisterQuery = (data?: RegisterReq) => Promise<AxiosResponse<UserResponse>>;
+type MeQuery = (data?: EmptyReq, authToken?: string) => Promise<AxiosResponse<UserResponse>>;
+
+export type AuthClient = {
+  login: LoginQuery;
+  me: MeQuery;
+  register: RegisterQuery;
+};
+
+export function auth(config: AxiosRequestConfig): AuthClient {
+  const axios = Axios.create({
+    ...config,
+    baseURL: `${config.baseURL}/api/auth`,
+  });
+
+  const login: LoginQuery = (data?: LoginReq): Promise<AxiosResponse<UserResponse>> => {
+    return axios.post<UserResponse>('/login', data);
+  };
+
+  const register: RegisterQuery = (data?: RegisterReq): Promise<AxiosResponse<UserResponse>> => {
+    return axios.post<UserResponse>('/register', data);
+  };
+
+  const me: MeQuery = (
+    data?: undefined,
+    authToken?: string,
+  ): Promise<AxiosResponse<UserResponse>> => {
+    return axios.get<UserResponse>('/me', {
+      headers: { Authorization: `Bearer ${authToken}` },
+    });
+  };
+
+  return {
+    login,
+    register,
+    me,
+  };
+}
diff --git a/src/client/client.ts b/src/client/client.ts
new file mode 100644
index 0000000000000000000000000000000000000000..062ff8145dd6185b309d2d707084b75fe925bc92
--- /dev/null
+++ b/src/client/client.ts
@@ -0,0 +1,23 @@
+import { AxiosRequestConfig } from 'axios';
+import { auth, AuthClient } from './auth';
+
+const DEFAULT_BASE_URL = '';
+
+export function createClient(
+  baseURL = DEFAULT_BASE_URL,
+  configOverride?: AxiosRequestConfig,
+): Client {
+  const config: AxiosRequestConfig = {
+    baseURL,
+    withCredentials: true,
+    ...configOverride,
+  };
+  const client = {
+    auth: auth(config),
+  };
+  return client;
+}
+
+export type Client = {
+  auth: AuthClient;
+};
diff --git a/src/client/types.ts b/src/client/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9b50c0f2e3bcf7ee76917538416c9428673b1c0e
--- /dev/null
+++ b/src/client/types.ts
@@ -0,0 +1,15 @@
+import { Profile } from '../types/types';
+
+export type EmptyReq = undefined;
+
+export type LoginReq = {
+  username: string;
+  password: string;
+};
+export type RegisterReq = {
+  username: string;
+  password: string;
+};
+export type UserResponse = {
+  user: Profile;
+};