diff --git a/apps/todo/package.json b/apps/todo/package.json
index dad3d3bfaaefca480ea087b85b35db99c83263f5..1799ed3b0e0364a17c02e555acd8d6b63e20903a 100644
--- a/apps/todo/package.json
+++ b/apps/todo/package.json
@@ -10,6 +10,8 @@
     "preview": "vite preview"
   },
   "dependencies": {
+    "@foss/query": "workspace:^",
+    "@tanstack/react-query": "^4.29.14",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
   },
diff --git a/apps/todo/src/App.tsx b/apps/todo/src/App.tsx
index afe48ac750194a747f5665300d14049f72011a33..e61934f283b643116590da3cc0634c7fb63ba75a 100644
--- a/apps/todo/src/App.tsx
+++ b/apps/todo/src/App.tsx
@@ -1,35 +1,43 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
+import "./App.css";
+import { useTodoQuery } from "@foss/query";
+import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
 
-function App() {
-  const [count, setCount] = useState(0)
+const queryClient = new QueryClient();
+
+function TodoComponent() {
+  const { data, isLoading } = useTodoQuery();
 
   return (
-    <>
+    <div>
+      {isLoading ? <p>Loading ... </p> : null}
       <div>
-        <a href="https://vitejs.dev" target="_blank">
-          <img src={viteLogo} className="logo" alt="Vite logo" />
-        </a>
-        <a href="https://react.dev" target="_blank">
-          <img src={reactLogo} className="logo react" alt="React logo" />
-        </a>
+        {data?.todos.map((todo) => (
+          <div key={`todo-${todo.id}`}>
+            <div>
+              <input
+                type="checkbox"
+                checked={todo.completed}
+                onChange={() => {
+                  /* noop */
+                }}
+              />
+              <span>
+                {todo.todo} (UserId: {todo.userId})
+              </span>
+            </div>
+          </div>
+        ))}
       </div>
-      <h1>Vite + React</h1>
-      <div className="card">
-        <button onClick={() => setCount((count) => count + 1)}>
-          count is {count}
-        </button>
-        <p>
-          Edit <code>src/App.tsx</code> and save to test HMR
-        </p>
-      </div>
-      <p className="read-the-docs">
-        Click on the Vite and React logos to learn more
-      </p>
-    </>
-  )
+    </div>
+  );
+}
+
+function App() {
+  return (
+    <QueryClientProvider client={queryClient}>
+      <TodoComponent />
+    </QueryClientProvider>
+  );
 }
 
-export default App
+export default App;
diff --git a/package.json b/package.json
index a7a53ae07d10d7688a1289d6ca63730ef1f8b170..f40fa16c70b057b59d5ef6bd7408d6076a635207 100644
--- a/package.json
+++ b/package.json
@@ -8,5 +8,8 @@
   },
   "keywords": [],
   "author": "",
-  "license": "ISC"
+  "license": "ISC",
+  "devDependencies": {
+    "typescript": "^5.0.2"
+  }
 }
diff --git a/packages/query/index.ts b/packages/query/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6dc9a5756ece522542bf45769c0e8616e11775f5
--- /dev/null
+++ b/packages/query/index.ts
@@ -0,0 +1,22 @@
+import { useQuery } from "@tanstack/react-query";
+
+export type Todo = {
+  id: string;
+  todo: string;
+  completed: boolean;
+  userId: number;
+};
+
+export type TodoResponse = {
+  limit: number;
+  skip: 0;
+  todos: Todo[];
+  total: number;
+};
+
+export const useTodoQuery = () => {
+  return useQuery<TodoResponse>(["todo"], {
+    queryFn: () =>
+      fetch("https://dummyjson.com/todos").then((res) => res.json()),
+  });
+};
diff --git a/packages/query/package.json b/packages/query/package.json
index ee84412a365caceb64bf0071d5129c5636fa1f41..9714116e486e4fa3967344598f174ad7fb770235 100644
--- a/packages/query/package.json
+++ b/packages/query/package.json
@@ -1,12 +1,18 @@
 {
-  "name": "query",
-  "version": "1.0.0",
-  "description": "",
-  "main": "index.js",
+  "name": "@foss/query",
+  "version": "0.0.0",
+  "main": "index.ts",
+  "types": "index.ts",
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "keywords": [],
   "author": "",
-  "license": "ISC"
+  "license": "ISC",
+  "dependencies": {
+    "@tanstack/react-query": "^4.29.14"
+  },
+  "peerDependencies": {
+    "@tanstack/react-query": "*"
+  }
 }
diff --git a/packages/query/tsconfig.json b/packages/query/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ffa57bad5e18cafcc58738053bcb2d309cabaf4
--- /dev/null
+++ b/packages/query/tsconfig.json
@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "target": "es2016",
+    "module": "commonjs",
+    "esModuleInterop": true,
+    "forceConsistentCasingInFileNames": true,
+    "strict": true,
+    "skipLibCheck": true
+  }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b55e220943626237142e69693227fb7ec121788f..667ef0a2381ef76f40caeacabcc3f6342078abcc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,10 +6,20 @@ settings:
 
 importers:
 
-  .: {}
+  .:
+    devDependencies:
+      typescript:
+        specifier: ^5.0.2
+        version: 5.0.2
 
   apps/todo:
     dependencies:
+      '@foss/query':
+        specifier: workspace:^
+        version: link:../../packages/query
+      '@tanstack/react-query':
+        specifier: ^4.29.14
+        version: 4.29.14(react-dom@18.2.0)(react@18.2.0)
       react:
         specifier: ^18.2.0
         version: 18.2.0
@@ -48,7 +58,11 @@ importers:
         specifier: ^4.3.9
         version: 4.3.9
 
-  packages/query: {}
+  packages/query:
+    dependencies:
+      '@tanstack/react-query':
+        specifier: ^4.29.14
+        version: 4.29.14(react-dom@18.2.0)(react@18.2.0)
 
 packages:
 
@@ -590,6 +604,28 @@ packages:
       fastq: 1.15.0
     dev: true
 
+  /@tanstack/query-core@4.29.14:
+    resolution: {integrity: sha512-ElEAahtLWA7Y7c2Haw10KdEf2tx+XZl/Z8dmyWxZehxWK3TPL5qtXtb7kUEhvt/8u2cSP62fLxgh2qqzMMGnDQ==}
+    dev: false
+
+  /@tanstack/react-query@4.29.14(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-wh4bd/QIy85YgTDBtj/7/9ZkpRX41QdZuUL8xKoSzuMCukXvAE1/oJ4p0F15lqQq9W3g2pgcbr2Aa+CNvqABhg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-native: '*'
+    peerDependenciesMeta:
+      react-dom:
+        optional: true
+      react-native:
+        optional: true
+    dependencies:
+      '@tanstack/query-core': 4.29.14
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+      use-sync-external-store: 1.2.0(react@18.2.0)
+    dev: false
+
   /@types/json-schema@7.0.12:
     resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
     dev: true
@@ -1705,6 +1741,14 @@ packages:
       punycode: 2.3.0
     dev: true
 
+  /use-sync-external-store@1.2.0(react@18.2.0):
+    resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      react: 18.2.0
+    dev: false
+
   /vite@4.3.9:
     resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
     engines: {node: ^14.18.0 || >=16.0.0}