diff --git a/ecs/src/update_testing.rs b/ecs/src/update_testing.rs
index 36ff4ad..215d86d 100644
--- a/ecs/src/update_testing.rs
+++ b/ecs/src/update_testing.rs
@@ -129,7 +129,7 @@ macro_rules! impl_query_singleton_update {
     };
 }
 
-impl_query_singleton_update!(R);
+impl_query_singleton_update!(R, U);
 
 struct T {}
 
@@ -145,10 +145,24 @@ impl ComponentDebug for T {
     }
 }
 
-fn system(_commands: &mut Commands, mut _query: Query<&mut T>) -> Result<()> {
+struct U {}
+
+impl EntityComponent for U {
+    fn name(&self) -> &str {
+        Self::debug_name()
+    }
+}
+
+impl ComponentDebug for U {
+    fn debug_name() -> &'static str {
+        "U"
+    }
+}
+
+fn system(_commands: &mut Commands, mut _query: Query<(&mut T, &mut U)>) -> Result<()> {
     Ok(())
 }
 
 fn test() {
-    // let q = QueryArchetype::create(system);
+    let q = QueryArchetype::create(system);
 }
diff --git a/ecs/src/updates.rs b/ecs/src/updates.rs
index 55ffdba..0b656c8 100644
--- a/ecs/src/updates.rs
+++ b/ecs/src/updates.rs
@@ -1,6 +1,7 @@
 #![allow(clippy::type_complexity)]
 
-use std::any::TypeId;
+use std::ops::{Deref, DerefMut};
+use std::{any::TypeId, marker::PhantomData};
 
 use std::collections::HashMap;
 #[cfg(feature = "timings")]
@@ -21,16 +22,16 @@ macro_rules! impl_singleton_update {
     ( $($var:ident $(,)?)+ ) => {
         impl<Func, Filter, $( $var, )+> CreateArchetype<( $( $var, )+ ), (), Func, Filter> for Archetype
         where
-            Func: Fn(&mut Commands, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(&mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static,
             $(
                 $var: EntityComponent + ComponentDebug,
             )+
         {
             paste::item! {
-                fn create(f: Func, filter: Filter) -> Self {
+                fn create(f: Func) -> Self {
                     $(
-                        filter.verify_dedup::<$var>();
+                        Filter::verify_dedup::<$var>();
                     )+
 
                     Self {
@@ -42,7 +43,7 @@ macro_rules! impl_singleton_update {
                                     }
                                 )+
 
-                                if !filter.check(entity) {
+                                if !Filter::check(entity) {
                                     return false;
                                 }
 
@@ -57,10 +58,17 @@ macro_rules! impl_singleton_update {
                                 );
                             )+
 
+                            let e = entity.as_entity();
                             let f = f.clone();
 
-                            Ok(Box::new(move |e, commands, _world| {
-                                unsafe { f(commands, e, $([< $var:lower >].as_mut(),)+) }
+                            Ok(Box::new(move |commands, _world| {
+                                let query = Query {
+                                    entity: e,
+                                    c:  unsafe { ($([< $var:lower >].as_mut(),)+) },
+                                    filter: PhantomData,
+                                };
+
+                                f(commands, query)
                             }))
                         }),
 
@@ -75,7 +83,7 @@ macro_rules! impl_singleton_update {
             $(
                 $var: EntityComponent + ComponentDebug,
             )+
-            Func: Fn(& mut Commands, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static
         {
             fn add_update(
@@ -83,10 +91,9 @@ macro_rules! impl_singleton_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: Filter
             ) -> Result<()> {
                 paste::item! {
-                    self.add(name, priority, Update::Single(Archetype::create(func, filter)))
+                    self.add(name, priority, Update::Single(Archetype::create(func)))
                 }
             }
         }
@@ -96,7 +103,7 @@ macro_rules! impl_singleton_update {
             $(
                 $var: EntityComponent + ComponentDebug,
             )+
-            Func: Fn(& mut Commands, Entity, $(&mut $var,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static
         {
             fn add_update(
@@ -104,9 +111,8 @@ macro_rules! impl_singleton_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: Filter,
             ) -> Result<()> {
-                self.updates.add_update(name, priority, func, filter)
+                self.updates.add_update(name, priority, func)
             }
         }
     };
@@ -114,7 +120,7 @@ macro_rules! impl_singleton_update {
     ( $($var:ident $(,)?)+ [$($res:ident $(,)?)+] ) => {
         impl<Func, Filter, $( $var, )+ $( $res, )+> CreateArchetype<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Archetype
         where
-            Func: Fn(&mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(&mut Commands, Query<( $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static,
             $(
                 $var: EntityComponent + ComponentDebug,
@@ -124,9 +130,9 @@ macro_rules! impl_singleton_update {
             )+
         {
             paste::item! {
-                fn create(f: Func, filter: Filter) -> Self {
+                fn create(f: Func) -> Self {
                     $(
-                        filter.verify_dedup::<$var>();
+                        Filter::verify_dedup::<$var>();
                     )+
 
                     Self {
@@ -138,7 +144,7 @@ macro_rules! impl_singleton_update {
                                     }
                                 )+
 
-                                if !filter.check(entity) {
+                                if !Filter::check(entity) {
                                     return false;
                                 }
 
@@ -153,9 +159,10 @@ macro_rules! impl_singleton_update {
                                 );
                             )+
 
+                            let e = entity.as_entity();
                             let f = f.clone();
 
-                            Ok(Box::new(move |e, commands, world| {
+                            Ok(Box::new(move |commands, world| {
 
                                 let (
                                     $(
@@ -167,7 +174,13 @@ macro_rules! impl_singleton_update {
                                     )+
                                 ) = world.resources.get_mut()?;
 
-                                unsafe { f(commands, e, $([< $var:lower >].as_mut(),)+ $([< $res:lower _var >],)+) }
+                                let query = Query {
+                                    entity: e,
+                                    c:  unsafe { ($([< $var:lower >].as_mut(),)+) },
+                                    filter: PhantomData,
+                                };
+
+                                f(commands, query, $([< $res:lower _var >],)+)
                             }))
                         }),
 
@@ -185,7 +198,7 @@ macro_rules! impl_singleton_update {
             $(
                 $res: ResourceTrait,
             )+
-            Func: Fn(& mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static
         {
             fn add_update(
@@ -193,10 +206,9 @@ macro_rules! impl_singleton_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: Filter
             ) -> Result<()> {
                 paste::item! {
-                    self.add(name, priority, Update::Single(Archetype::create(func, filter)))
+                    self.add(name, priority, Update::Single(Archetype::create(func)))
                 }
             }
         }
@@ -209,7 +221,7 @@ macro_rules! impl_singleton_update {
             $(
                 $res: ResourceTrait,
             )+
-            Func: Fn(& mut Commands, Entity, $(&mut $var,)+ $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
             Filter: CheckFilter + 'static
         {
             fn add_update(
@@ -217,9 +229,8 @@ macro_rules! impl_singleton_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: Filter,
             ) -> Result<()> {
-                self.updates.add_update(name, priority, func, filter)
+                self.updates.add_update(name, priority, func)
             }
         }
     };
@@ -235,9 +246,9 @@ macro_rules! impl_pair_update {
         impl ArchetypePair {
             paste::item! {
                 pub fn [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $($lhs_big,)+ $($rhs_big,)+>
-                    (f: F, left_filter: LeftFilter, right_filter: RightFilter) -> Self
+                    (f: F) -> Self
                 where
-                    F: Fn(&mut Commands, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
+                    F: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LeftFilter>, Query<( $( &mut $rhs_big, )+ ), RightFilter>) -> Result<()> + Send + Sync + Clone + 'static,
                     LeftFilter: CheckFilter + 'static,
                     RightFilter: CheckFilter + 'static,
                     $(
@@ -248,11 +259,11 @@ macro_rules! impl_pair_update {
                     )+
                 {
                     $(
-                        left_filter.verify_dedup::<$lhs_big>();
+                        LeftFilter::verify_dedup::<$lhs_big>();
                     )+
 
                     $(
-                        right_filter.verify_dedup::<$rhs_big>();
+                        RightFilter::verify_dedup::<$rhs_big>();
                     )+
 
                     Self {
@@ -264,7 +275,7 @@ macro_rules! impl_pair_update {
                                     }
                                 )+
 
-                                if !left_filter.check(entity) {
+                                if !LeftFilter::check(entity) {
                                     return false;
                                 }
 
@@ -279,7 +290,7 @@ macro_rules! impl_pair_update {
                                     }
                                 )+
 
-                                if !right_filter.check(entity) {
+                                if !RightFilter::check(entity) {
                                     return false;
                                 }
 
@@ -300,10 +311,24 @@ macro_rules! impl_pair_update {
                                 );
                             )+
 
+                            let lhs_e = lhs_entity.as_entity();
+                            let rhs_e = rhs_entity.as_entity();
                             let f = f.clone();
 
-                            Ok(Box::new(move |lhs_e, rhs_e, commands| {
-                                unsafe { f(commands, (lhs_e, $($lhs_little.as_mut(),)+), (rhs_e, $($rhs_little.as_mut(),)+) ) }
+                            Ok(Box::new(move |commands| {
+                                let lhs_query = Query {
+                                    entity: lhs_e,
+                                    c:  unsafe { ($($lhs_little.as_mut(),)+) },
+                                    filter: PhantomData,
+                                };
+
+                                let rhs_query = Query {
+                                    entity: rhs_e,
+                                    c:  unsafe { ($($rhs_little.as_mut(),)+) },
+                                    filter: PhantomData,
+                                };
+
+                                f(commands, lhs_query, rhs_query )
                             }))
                         }),
 
@@ -321,7 +346,7 @@ macro_rules! impl_pair_update {
             $(
                 $lhs_big: EntityComponent + ComponentDebug,
             )+
-            Func: Fn(&mut Commands, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static,
             LhsFilter: CheckFilter + 'static,
             RhsFilter: CheckFilter + 'static
         {
@@ -330,10 +355,9 @@ macro_rules! impl_pair_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: (LhsFilter, RhsFilter)
             ) -> Result<()> {
                 paste::item! {
-                    self.add(name, priority, Update::Pair(ArchetypePair::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func, filter.0, filter.1)))?;
+                    self.add(name, priority, Update::Pair(ArchetypePair::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func)))?;
                 }
 
                 Ok(())
@@ -348,7 +372,7 @@ macro_rules! impl_pair_update {
             $(
                 $lhs_big: EntityComponent + ComponentDebug,
             )+
-            Func: Fn(& mut Commands, (Entity, $(&mut $lhs_big,)+), (Entity, $(&mut $rhs_big,)+)) -> Result<()> + Send + Sync + Clone + 'static,
+            Func: Fn(& mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static,
             LhsFilter: CheckFilter + 'static,
             RhsFilter: CheckFilter + 'static
         {
@@ -357,9 +381,8 @@ macro_rules! impl_pair_update {
                 name: &str,
                 priority: u32,
                 func: Func,
-                filter: (LhsFilter, RhsFilter),
             ) -> Result<()> {
-                self.updates.add_update(name, priority, func, filter)
+                self.updates.add_update(name, priority, func)
             }
         }
     };
@@ -385,7 +408,7 @@ macro_rules! impl_update_filter {
             }
 
             impl<$($big: EntityComponent,)+> CheckFilter for [<$name Filter>]<$($big,)+> {
-                fn check(&self, entity: &EntityObject) -> bool {
+                fn check(entity: &EntityObject) -> bool {
                     $(
                         if entity.contains_component::<$big>() {
                             return false;
@@ -395,7 +418,7 @@ macro_rules! impl_update_filter {
                     true
                 }
 
-                fn verify_dedup<O: EntityComponent>(&self) {
+                fn verify_dedup<O: EntityComponent>() {
                     $(
                         if TypeId::of::<O>() == TypeId::of::<$big>() {
                             panic!("Type is used as input and filter at the same time");
@@ -417,28 +440,58 @@ macro_rules! impl_update_filter {
     };
 }
 
+#[derive(Copy, Clone)]
+pub struct Query<C, F = EmptyFilter>
+where
+    F: CheckFilter,
+{
+    entity: Entity,
+    c: C,
+    filter: PhantomData<F>,
+}
+
+impl<C, F: CheckFilter> Query<C, F> {
+    pub fn entity(&self) -> Entity {
+        self.entity
+    }
+}
+
+impl<C, F: CheckFilter> Deref for Query<C, F> {
+    type Target = C;
+
+    fn deref(&self) -> &Self::Target {
+        &self.c
+    }
+}
+
+impl<C, F: CheckFilter> DerefMut for Query<C, F> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.c
+    }
+}
+
 pub trait AddUpdates<T, R, Func, Filter> {
-    fn add_update(&mut self, name: &str, priority: u32, func: Func, filter: Filter) -> Result<()>;
+    fn add_update(&mut self, name: &str, priority: u32, func: Func) -> Result<()>;
 }
 
 trait CreateArchetype<T, R, Func, Filter> {
-    fn create(f: Func, filter: Filter) -> Self;
+    fn create(f: Func) -> Self;
 }
 
 pub trait CheckFilter: Send + Sync + Default + Clone {
-    fn check(&self, entity: &EntityObject) -> bool;
-    fn verify_dedup<O: EntityComponent>(&self);
+    fn check(entity: &EntityObject) -> bool;
+    fn verify_dedup<O: EntityComponent>();
 }
 
 #[derive(Default, Clone)]
 pub struct EmptyFilter;
 
 impl CheckFilter for EmptyFilter {
-    fn check(&self, _entity: &EntityObject) -> bool {
+    fn check(_entity: &EntityObject) -> bool {
         true
     }
 
-    fn verify_dedup<O>(&self) {}
+    fn verify_dedup<O>() {}
 }
 
 #[derive(Default, Clone, Debug)]
@@ -466,15 +519,12 @@ pub struct Archetype {
         dyn Fn(
                 &EntityObject,
             )
-                -> Result<Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>>
+                -> Result<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>
             + Send
             + Sync,
     >,
 
-    entities: IndexMap<
-        Entity,
-        Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>,
-    >,
+    entities: IndexMap<Entity, Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>,
 }
 
 impl Archetype {
@@ -495,8 +545,8 @@ impl Archetype {
     pub fn execute(&self, world: &mut World) -> Result<()> {
         let mut commands = Commands::new(world.now());
 
-        for (entity, callback) in self.entities.iter() {
-            callback(*entity, &mut commands, world)?;
+        for callback in self.entities.values() {
+            callback(&mut commands, world)?;
         }
 
         commands.apply_deferred(world)?;
@@ -506,9 +556,13 @@ impl Archetype {
 
     pub fn entities(
         &self,
-    ) -> &IndexMap<Entity, Box<dyn Fn(Entity, &mut Commands, &mut World) -> Result<()> + Send + Sync>>
-    {
-        &self.entities
+    ) -> impl Iterator<
+        Item = (
+            &Entity,
+            &Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>,
+        ),
+    > {
+        self.entities.iter()
     }
 }
 
@@ -520,16 +574,12 @@ pub struct ArchetypePair {
         dyn Fn(
                 &EntityObject,
                 &EntityObject,
-            )
-                -> Result<Box<dyn Fn(Entity, Entity, &mut Commands) -> Result<()> + Send + Sync>>
+            ) -> Result<Box<dyn Fn(&mut Commands) -> Result<()> + Send + Sync>>
             + Send
             + Sync,
     >,
 
-    entities: IndexMap<
-        (Entity, Entity),
-        Box<dyn Fn(Entity, Entity, &mut Commands) -> Result<()> + Send + Sync>,
-    >,
+    entities: IndexMap<(Entity, Entity), Box<dyn Fn(&mut Commands) -> Result<()> + Send + Sync>>,
 }
 
 impl ArchetypePair {
@@ -549,8 +599,10 @@ impl ArchetypePair {
             {
                 let cb = (self.create_callback)(entity_object, other_entity_object)?;
 
-                self.entities
-                    .insert((entity_object.as_entity(), *other_entity), cb);
+                self.entities.insert(
+                    (entity_object.as_entity(), other_entity_object.as_entity()),
+                    cb,
+                );
             }
 
             if (self.check_left_entity)(other_entity_object)
@@ -558,8 +610,10 @@ impl ArchetypePair {
             {
                 let cb = (self.create_callback)(other_entity_object, entity_object)?;
 
-                self.entities
-                    .insert((*other_entity, entity_object.as_entity()), cb);
+                self.entities.insert(
+                    (other_entity_object.as_entity(), entity_object.as_entity()),
+                    cb,
+                );
             }
         }
 
@@ -580,8 +634,8 @@ impl ArchetypePair {
     pub(crate) fn execute(&self, world: &mut World) -> Result<()> {
         let mut commands = Commands::new(world.now());
 
-        for ((left_entity, right_entity), callback) in self.entities.iter() {
-            callback(*left_entity, *right_entity, &mut commands)?;
+        for callback in self.entities.values() {
+            callback(&mut commands)?;
         }
 
         commands.apply_deferred(world)?;
diff --git a/ecs/src/world.rs b/ecs/src/world.rs
index b1e4926..a52705b 100644
--- a/ecs/src/world.rs
+++ b/ecs/src/world.rs
@@ -278,14 +278,14 @@ impl World {
 
         let mut entities = Vec::new();
 
-        for entity in archetype.entities().keys() {
+        for (&entity, _) in archetype.entities() {
             #[cfg(debug_assertions)]
-            let debug_name = self.entity(*entity)?.debug_name.clone();
+            let debug_name = self.entity(entity)?.debug_name.clone();
 
             #[cfg(not(debug_assertions))]
             let debug_name = None;
 
-            entities.push((*entity, debug_name));
+            entities.push((entity, debug_name));
         }
 
         Ok(ArchetypeInfo::new(entities))